aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/Define.h1
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.cpp13
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h3
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.cpp517
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h108
-rw-r--r--src/server/game/AI/ScriptedAI/ScriptedCreature.cpp2
-rw-r--r--src/server/game/AI/SmartScripts/SmartScriptMgr.h2
-rw-r--r--src/server/game/Achievements/AchievementMgr.cpp6
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.cpp7
-rw-r--r--src/server/game/AuctionHouse/AuctionHouseMgr.h5
-rw-r--r--src/server/game/AuctionHouseBot/AuctionHouseBotSeller.cpp1
-rw-r--r--src/server/game/Chat/ChatLink.cpp21
-rw-r--r--src/server/game/Conditions/ConditionMgr.cpp12
-rw-r--r--src/server/game/DataStores/DB2Stores.cpp268
-rw-r--r--src/server/game/DataStores/DB2Stores.h65
-rw-r--r--src/server/game/DataStores/DB2Structure.h2024
-rw-r--r--src/server/game/DataStores/DB2fmt.h257
-rw-r--r--src/server/game/DataStores/DBCEnums.h1
-rw-r--r--src/server/game/DataStores/DBCStores.cpp401
-rw-r--r--src/server/game/DataStores/DBCStores.h81
-rw-r--r--src/server/game/DataStores/DBCStructure.h596
-rw-r--r--src/server/game/DataStores/DBCfmt.h72
-rw-r--r--src/server/game/Entities/GameObject/GameObject.cpp12
-rw-r--r--src/server/game/Entities/Item/Item.cpp184
-rw-r--r--src/server/game/Entities/Item/ItemEnchantmentMgr.cpp2
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.cpp52
-rw-r--r--src/server/game/Entities/Item/ItemTemplate.h37
-rw-r--r--src/server/game/Entities/Object/Object.cpp7
-rw-r--r--src/server/game/Entities/Object/Object.h1
-rw-r--r--src/server/game/Entities/Player/Player.cpp306
-rw-r--r--src/server/game/Entities/Player/Player.h59
-rw-r--r--src/server/game/Entities/Taxi/TaxiPathGraph.cpp4
-rw-r--r--src/server/game/Entities/Unit/StatSystem.cpp27
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp78
-rw-r--r--src/server/game/Entities/Unit/Unit.h2
-rw-r--r--src/server/game/Garrison/Garrison.cpp34
-rw-r--r--src/server/game/Garrison/Garrison.h1
-rw-r--r--src/server/game/Garrison/GarrisonMgr.cpp34
-rw-r--r--src/server/game/Garrison/GarrisonMgr.h12
-rw-r--r--src/server/game/Globals/ObjectMgr.cpp45
-rw-r--r--src/server/game/Guilds/Guild.cpp4
-rw-r--r--src/server/game/Guilds/GuildMgr.cpp6
-rw-r--r--src/server/game/Handlers/AuctionHouseHandler.cpp5
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp8
-rw-r--r--src/server/game/Handlers/ItemHandler.cpp69
-rw-r--r--src/server/game/Handlers/SkillHandler.cpp2
-rw-r--r--src/server/game/Loot/LootMgr.cpp2
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h27
-rw-r--r--src/server/game/Server/Packets/SpellPackets.cpp15
-rw-r--r--src/server/game/Server/Packets/SpellPackets.h19
-rw-r--r--src/server/game/Server/Protocol/Opcodes.cpp1
-rw-r--r--src/server/game/Server/Protocol/Opcodes.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.cpp48
-rw-r--r--src/server/game/Spells/Auras/SpellAuraEffects.h1
-rw-r--r--src/server/game/Spells/Auras/SpellAuras.cpp15
-rw-r--r--src/server/game/Spells/Spell.cpp138
-rw-r--r--src/server/game/Spells/Spell.h2
-rw-r--r--src/server/game/Spells/SpellEffects.cpp56
-rw-r--r--src/server/game/Spells/SpellHistory.cpp52
-rw-r--r--src/server/game/Spells/SpellHistory.h12
-rw-r--r--src/server/game/Spells/SpellInfo.cpp207
-rw-r--r--src/server/game/Spells/SpellInfo.h53
-rw-r--r--src/server/game/Spells/SpellMgr.cpp77
-rw-r--r--src/server/game/Spells/SpellMgr.h21
-rw-r--r--src/server/game/Texts/CreatureTextMgr.cpp2
-rw-r--r--src/server/scripts/Commands/cs_debug.cpp2
-rw-r--r--src/server/scripts/Commands/cs_learn.cpp37
-rw-r--r--src/server/scripts/Commands/cs_list.cpp2
-rw-r--r--src/server/scripts/Commands/cs_lookup.cpp242
-rw-r--r--src/server/scripts/Commands/cs_misc.cpp18
-rw-r--r--src/server/scripts/Spells/spell_druid.cpp14
-rw-r--r--src/server/scripts/Spells/spell_item.cpp2
-rw-r--r--src/server/shared/DataStores/DB2SparseStorageLoader.cpp683
-rw-r--r--src/server/shared/DataStores/DB2SparseStorageLoader.h117
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.cpp180
-rw-r--r--src/server/shared/DataStores/DB2StorageLoader.h40
-rw-r--r--src/server/shared/DataStores/DB2Store.h226
-rw-r--r--src/server/shared/DataStores/DBCFileLoader.cpp20
-rw-r--r--src/server/shared/DataStores/DBStorageIterator.h7
79 files changed, 4287 insertions, 3506 deletions
diff --git a/src/common/Define.h b/src/common/Define.h
index 35a4dad3e1b..c9eb42791e9 100644
--- a/src/common/Define.h
+++ b/src/common/Define.h
@@ -167,6 +167,7 @@ enum DBCFormer
FT_INT = 'i', //uint32
FT_BYTE = 'b', //uint8
FT_LONG = 'l', //uint64
+ FT_SHORT = 'h', //uint16
FT_SORT = 'd', //sorted by this field, field is not included
FT_IND = 'n', //the same, but parsed to data
FT_SQL_PRESENT = 'p', //Used in sql format to mark column present in sql dbc
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp
index 6450946aaa4..6399b588b5d 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.cpp
+++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp
@@ -22,7 +22,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
if (!m_reconnecting)
m_stmts.resize(MAX_CHARACTERDATABASE_STATEMENTS);
-#define SelectItemInstanceContent "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, ii.enchantIllusion, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.bonusListIDs"
+#define SelectItemInstanceContent "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, ii.enchantIllusion, ii.battlePetSpeciesId, ii.battlePetBreedData, ii.battlePetLevel, ii.battlePetDisplayId, ii.bonusListIDs, ig.gemItemId1, ig.gemItemId2, ig.gemItemId3"
PrepareStatement(CHAR_DEL_QUEST_POOL_SAVE, "DELETE FROM pool_quest_save WHERE pool_id = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_INS_QUEST_POOL_SAVE, "INSERT INTO pool_quest_save (pool_id, quest_id) VALUES (?, ?)", CONNECTION_ASYNC);
@@ -108,7 +108,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_DEL_RESET_CHARACTER_QUESTSTATUS_SEASONAL_BY_EVENT, "DELETE FROM character_queststatus_seasonal WHERE event = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_REPUTATION, "SELECT faction, standing, flags FROM character_reputation WHERE guid = ?", CONNECTION_ASYNC);
- PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT " SelectItemInstanceContent ", bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_SEL_CHARACTER_INVENTORY, "SELECT " SelectItemInstanceContent ", bag, slot FROM character_inventory ci JOIN item_instance ii ON ci.item = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid WHERE ci.guid = ? ORDER BY bag, slot", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS, "SELECT a.button, a.action, a.type FROM character_action as a, characters as c WHERE a.guid = c.guid AND a.spec = c.activeTalentGroup AND a.guid = ? ORDER BY button", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_MAILCOUNT, "SELECT COUNT(id) FROM mail WHERE receiver = ? AND (checked & 1) = 0 AND deliver_time <= ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_MAILDATE, "SELECT MIN(deliver_time) FROM mail WHERE receiver = ? AND (checked & 1) = 0", CONNECTION_ASYNC);
@@ -136,8 +136,8 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_SEL_ACCOUNT_INSTANCELOCKTIMES, "SELECT instanceId, releaseTime FROM account_instance_times WHERE accountId = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_ACTIONS_SPEC, "SELECT button, action, type FROM character_action WHERE guid = ? AND spec = ? ORDER BY button", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT " SelectItemInstanceContent ", ii.owner_guid FROM mail_items mi JOIN item_instance ii ON mi.item_guid = ii.guid WHERE mail_id = ?", CONNECTION_SYNCH);
- PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT " SelectItemInstanceContent " FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_MAILITEMS, "SELECT " SelectItemInstanceContent ", ii.owner_guid FROM mail_items mi JOIN item_instance ii ON mi.item_guid = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid WHERE mail_id = ?", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_AUCTION_ITEMS, "SELECT " SelectItemInstanceContent " FROM auctionhouse ah JOIN item_instance ii ON ah.itemguid = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid", CONNECTION_SYNCH);
PrepareStatement(CHAR_SEL_AUCTIONS, "SELECT id, auctioneerguid, itemguid, itemEntry, count, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit FROM auctionhouse ah INNER JOIN item_instance ii ON ii.guid = ah.itemguid", CONNECTION_SYNCH);
PrepareStatement(CHAR_INS_AUCTION, "INSERT INTO auctionhouse (id, auctioneerguid, itemguid, itemowner, buyoutprice, time, buyguid, lastbid, startbid, deposit) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_AUCTION, "DELETE FROM auctionhouse WHERE id = ?", CONNECTION_ASYNC);
@@ -164,6 +164,9 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_ITEM_INSTANCE_ON_LOAD, "UPDATE item_instance SET duration = ?, flags = ?, durability = ? WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE, "DELETE FROM item_instance WHERE guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_ITEM_INSTANCE_BY_OWNER, "DELETE FROM item_instance WHERE owner_guid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_INS_ITEM_INSTANCE_GEMS, "INSERT INTO item_instance_gems (itemGuid, gemItemId1, gemItemId2, gemItemId3) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_ITEM_INSTANCE_GEMS, "DELETE FROM item_instance_gems WHERE itemGuid = ?", CONNECTION_ASYNC);
+ PrepareStatement(CHAR_DEL_ITEM_INSTANCE_GEMS_BY_OWNER, "DELETE iig FROM item_instance_gems iig LEFT JOIN item_instance ii ON iig.itemGuid = ii.guid WHERE ii.owner_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_GIFT_OWNER, "UPDATE character_gifts SET guid = ? WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GIFT, "DELETE FROM character_gifts WHERE item_guid = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_SEL_CHARACTER_GIFT_BY_ITEM, "SELECT entry, flags FROM character_gifts WHERE item_guid = ?", CONNECTION_SYNCH);
@@ -195,7 +198,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
// 0: uint32, 1: uint8, 2: uint8, 3: uint32, 4: uint32
PrepareStatement(CHAR_INS_GUILD_BANK_ITEM, "INSERT INTO guild_bank_item (guildid, TabId, SlotId, item_guid) VALUES (?, ?, ?, ?)", CONNECTION_ASYNC);
PrepareStatement(CHAR_DEL_GUILD_BANK_ITEM, "DELETE FROM guild_bank_item WHERE guildid = ? AND TabId = ? AND SlotId = ?", CONNECTION_ASYNC); // 0: uint32, 1: uint8, 2: uint8
- PrepareStatement(CHAR_SEL_GUILD_BANK_ITEMS, "SELECT " SelectItemInstanceContent ", guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid", CONNECTION_SYNCH);
+ PrepareStatement(CHAR_SEL_GUILD_BANK_ITEMS, "SELECT " SelectItemInstanceContent ", guildid, TabId, SlotId FROM guild_bank_item gbi INNER JOIN item_instance ii ON gbi.item_guid = ii.guid LEFT JOIN item_instance_gems ig ON ii.guid = ig.itemGuid", CONNECTION_SYNCH);
PrepareStatement(CHAR_DEL_GUILD_BANK_ITEMS, "DELETE FROM guild_bank_item WHERE guildid = ?", CONNECTION_ASYNC); // 0: uint32
// 0: uint32, 1: uint8, 2: uint8, 3: uint8, 4: uint32
PrepareStatement(CHAR_INS_GUILD_BANK_RIGHT, "INSERT INTO guild_bank_right (guildid, TabId, rid, gbright, SlotPerDay) VALUES (?, ?, ?, ?, ?) "
diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h
index 18faea4c5b0..e35bedfd587 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -144,6 +144,9 @@ enum CharacterDatabaseStatements
CHAR_UPD_ITEM_INSTANCE_ON_LOAD,
CHAR_DEL_ITEM_INSTANCE,
CHAR_DEL_ITEM_INSTANCE_BY_OWNER,
+ CHAR_INS_ITEM_INSTANCE_GEMS,
+ CHAR_DEL_ITEM_INSTANCE_GEMS,
+ CHAR_DEL_ITEM_INSTANCE_GEMS_BY_OWNER,
CHAR_UPD_GIFT_OWNER,
CHAR_DEL_GIFT,
CHAR_SEL_CHARACTER_GIFT_BY_ITEM,
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp
index 6749300000b..666b697a4c3 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.cpp
+++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp
@@ -31,120 +31,158 @@ void HotfixDatabaseConnection::DoPrepareStatements()
m_stmts.resize(MAX_HOTFIXDATABASE_STATEMENTS);
// Achievement.db2
- PrepareStatement(HOTFIX_SEL_ACHIEVEMENT, "SELECT ID, Faction, MapID, Supercedes, Title, Description, Category, Points, UIOrder, Flags, IconID, "
- "Reward, MinimumCriteria, SharesCriteria, CriteriaTree FROM achievement ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ACHIEVEMENT, "SELECT ID, Title, Description, Flags, Reward, MapID, Supercedes, Category, UIOrder, IconID, "
+ "SharesCriteria, CriteriaTree, Faction, Points, MinimumCriteria FROM achievement ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_ACHIEVEMENT, "SELECT ID, Title_lang, Description_lang, Reward_lang FROM achievement_locale WHERE locale = ?", CONNECTION_SYNCH);
+ // AnimKit.db2
+ PrepareStatement(HOTFIX_SEL_ANIM_KIT, "SELECT ID, OneShotDuration, OneShotStopAnimKitID, LowDefAnimKitID FROM anim_kit ORDER BY ID DESC", CONNECTION_SYNCH);
+
// AreaGroupMember.db2
PrepareStatement(HOTFIX_SEL_AREA_GROUP_MEMBER, "SELECT ID, AreaGroupID, AreaID FROM area_group_member ORDER BY ID DESC", CONNECTION_SYNCH);
+ // ArmorLocation.db2
+ PrepareStatement(HOTFIX_SEL_ARMOR_LOCATION, "SELECT ID, Modifier1, Modifier2, Modifier3, Modifier4, Modifier5 FROM armor_location ORDER BY ID DESC", CONNECTION_SYNCH);
+
// AuctionHouse.db2
- PrepareStatement(HOTFIX_SEL_AUCTION_HOUSE, "SELECT ID, FactionID, DepositRate, ConsignmentRate, Name FROM auction_house ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_AUCTION_HOUSE, "SELECT ID, Name, FactionID, DepositRate, ConsignmentRate FROM auction_house ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_AUCTION_HOUSE, "SELECT ID, Name_lang FROM auction_house_locale WHERE locale = ?", CONNECTION_SYNCH);
+ // BankBagSlotPrices.db2
+ PrepareStatement(HOTFIX_SEL_BANK_BAG_SLOT_PRICES, "SELECT ID, Cost FROM bank_bag_slot_prices ORDER BY ID DESC", CONNECTION_SYNCH);
+
// BarberShopStyle.db2
- PrepareStatement(HOTFIX_SEL_BARBER_SHOP_STYLE, "SELECT ID, Type, DisplayName, Description, CostModifier, Race, Sex, Data FROM barber_shop_style"
+ PrepareStatement(HOTFIX_SEL_BARBER_SHOP_STYLE, "SELECT ID, DisplayName, Description, CostModifier, Type, Race, Sex, Data FROM barber_shop_style"
" ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_BARBER_SHOP_STYLE, "SELECT ID, DisplayName_lang, Description_lang FROM barber_shop_style_locale WHERE locale = ?", CONNECTION_SYNCH);
// BattlePetBreedQuality.db2
- PrepareStatement(HOTFIX_SEL_BATTLE_PET_BREED_QUALITY, "SELECT ID, Quality, Modifier FROM battle_pet_breed_quality ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_BATTLE_PET_BREED_QUALITY, "SELECT ID, Modifier, Quality FROM battle_pet_breed_quality ORDER BY ID DESC", CONNECTION_SYNCH);
// BattlePetBreedState.db2
- PrepareStatement(HOTFIX_SEL_BATTLE_PET_BREED_STATE, "SELECT ID, BreedID, State, Value FROM battle_pet_breed_state ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_BATTLE_PET_BREED_STATE, "SELECT ID, Value, BreedID, State FROM battle_pet_breed_state ORDER BY ID DESC", CONNECTION_SYNCH);
// BattlePetSpecies.db2
- PrepareStatement(HOTFIX_SEL_BATTLE_PET_SPECIES, "SELECT ID, CreatureID, IconFileID, SummonSpellID, PetType, Source, Flags, SourceText, "
- "Description FROM battle_pet_species ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_BATTLE_PET_SPECIES, "SELECT ID, CreatureID, IconFileID, SummonSpellID, SourceText, Description, Flags, PetType, "
+ "Source FROM battle_pet_species ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_BATTLE_PET_SPECIES, "SELECT ID, SourceText_lang, Description_lang FROM battle_pet_species_locale WHERE locale = ?", CONNECTION_SYNCH);
// BattlePetSpeciesState.db2
- PrepareStatement(HOTFIX_SEL_BATTLE_PET_SPECIES_STATE, "SELECT ID, SpeciesID, State, Value FROM battle_pet_species_state ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_BATTLE_PET_SPECIES_STATE, "SELECT ID, Value, SpeciesID, State FROM battle_pet_species_state ORDER BY ID DESC", CONNECTION_SYNCH);
// BroadcastText.db2
- PrepareStatement(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, Language, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, "
- "EmoteDelay3, SoundID, UnkEmoteID, Type FROM broadcast_text ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, MaleText, FemaleText, EmoteID1, EmoteID2, EmoteID3, EmoteDelay1, EmoteDelay2, "
+ "EmoteDelay3, SoundID, UnkEmoteID, Language, Type FROM broadcast_text ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_BROADCAST_TEXT, "SELECT ID, MaleText_lang, FemaleText_lang FROM broadcast_text_locale WHERE locale = ?", CONNECTION_SYNCH);
// CharStartOutfit.db2
- PrepareStatement(HOTFIX_SEL_CHAR_START_OUTFIT, "SELECT ID, RaceID, ClassID, GenderID, OutfitID, ItemID1, ItemID2, ItemID3, ItemID4, ItemID5, "
- "ItemID6, ItemID7, ItemID8, ItemID9, ItemID10, ItemID11, ItemID12, ItemID13, ItemID14, ItemID15, ItemID16, ItemID17, ItemID18, ItemID19, "
- "ItemID20, ItemID21, ItemID22, ItemID23, ItemID24, PetDisplayID, PetFamilyID FROM char_start_outfit ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_CHAR_START_OUTFIT, "SELECT ID, ItemID1, ItemID2, ItemID3, ItemID4, ItemID5, ItemID6, ItemID7, ItemID8, ItemID9, "
+ "ItemID10, ItemID11, ItemID12, ItemID13, ItemID14, ItemID15, ItemID16, ItemID17, ItemID18, ItemID19, ItemID20, ItemID21, ItemID22, ItemID23, "
+ "ItemID24, PetDisplayID, RaceID, ClassID, GenderID, OutfitID, PetFamilyID FROM char_start_outfit ORDER BY ID DESC", CONNECTION_SYNCH);
// ChrClassesXPowerTypes.db2
PrepareStatement(HOTFIX_SEL_CHR_CLASSES_X_POWER_TYPES, "SELECT ID, ClassID, PowerType FROM chr_classes_x_power_types ORDER BY ID DESC", CONNECTION_SYNCH);
+ // ChrRaces.db2
+ PrepareStatement(HOTFIX_SEL_CHR_RACES, "SELECT ID, Flags, ClientPrefix, ClientFileString, Name, NameFemale, NameMale, FacialHairCustomization1, "
+ "FacialHairCustomization2, HairCustomization, CreateScreenFileDataID, SelectScreenFileDataID, MaleCustomizeOffset1, MaleCustomizeOffset2, "
+ "MaleCustomizeOffset3, FemaleCustomizeOffset1, FemaleCustomizeOffset2, FemaleCustomizeOffset3, LowResScreenFileDataID, FactionID, "
+ "ExplorationSoundID, MaleDisplayID, FemaleDisplayID, ResSicknessSpellID, SplashSoundID, CinematicSequenceID, UAMaleCreatureSoundDataID, "
+ "UAFemaleCreatureSoundDataID, HighResMaleDisplayID, HighResFemaleDisplayID, Unk, BaseLanguage, CreatureType, TeamID, RaceRelated, "
+ "UnalteredVisualRaceID, CharComponentTextureLayoutID, DefaultClassID, NeutralRaceID, CharComponentTexLayoutHiResID FROM chr_races"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_CHR_RACES, "SELECT ID, Name_lang, NameFemale_lang, NameMale_lang FROM chr_races_locale WHERE locale = ?", CONNECTION_SYNCH);
+
// CinematicSequences.db2
PrepareStatement(HOTFIX_SEL_CINEMATIC_SEQUENCES, "SELECT ID, SoundID, Camera1, Camera2, Camera3, Camera4, Camera5, Camera6, Camera7, Camera8"
" FROM cinematic_sequences ORDER BY ID DESC", CONNECTION_SYNCH);
// CreatureDisplayInfo.db2
- PrepareStatement(HOTFIX_SEL_CREATURE_DISPLAY_INFO, "SELECT ID, ModelID, SoundID, ExtendedDisplayInfoID, CreatureModelScale, PlayerModelScale, "
- "CreatureModelAlpha, TextureVariation1, TextureVariation2, TextureVariation3, PortraitTextureName, PortraitCreatureDisplayInfoID, SizeClass, "
- "BloodID, NPCSoundID, ParticleColorID, CreatureGeosetData, ObjectEffectPackageID, AnimReplacementSetID, Flags, Gender, StateSpellVisualKitID"
- " FROM creature_display_info ORDER BY ID DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMT(HOTFIX_SEL_CREATURE_DISPLAY_INFO, "SELECT ID, TextureVariation1_lang, TextureVariation2_lang, TextureVariation3_lang, "
- "PortraitTextureName_lang FROM creature_display_info_locale WHERE locale = ?", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_CREATURE_DISPLAY_INFO, "SELECT ID, ExtendedDisplayInfoID, CreatureModelScale, PlayerModelScale, TextureVariation1, "
+ "TextureVariation2, TextureVariation3, PortraitTextureName, PortraitCreatureDisplayInfoID, CreatureGeosetData, StateSpellVisualKitID, "
+ "ModelID, SoundID, NPCSoundID, ParticleColorID, ObjectEffectPackageID, AnimReplacementSetID, CreatureModelAlpha, SizeClass, BloodID, Flags, "
+ "Gender, Unk700 FROM creature_display_info ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // CreatureDisplayInfoExtra.db2
+ PrepareStatement(HOTFIX_SEL_CREATURE_DISPLAY_INFO_EXTRA, "SELECT ID, NPCItemDisplay1, NPCItemDisplay2, NPCItemDisplay3, NPCItemDisplay4, "
+ "NPCItemDisplay5, NPCItemDisplay6, NPCItemDisplay7, NPCItemDisplay8, NPCItemDisplay9, NPCItemDisplay10, FileDataID, HDFileDataID, "
+ "DisplayRaceID, DisplaySexID, DisplayClassID, SkinID, FaceID, HairStyleID, HairColorID, FacialHairID, CustomDisplayOption1, "
+ "CustomDisplayOption2, CustomDisplayOption3, Flags FROM creature_display_info_extra ORDER BY ID DESC", CONNECTION_SYNCH);
// CreatureType.db2
PrepareStatement(HOTFIX_SEL_CREATURE_TYPE, "SELECT ID, Name, Flags FROM creature_type ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_CREATURE_TYPE, "SELECT ID, Name_lang FROM creature_type_locale WHERE locale = ?", CONNECTION_SYNCH);
// Criteria.db2
- PrepareStatement(HOTFIX_SEL_CRITERIA, "SELECT ID, Type, Asset, StartEvent, StartAsset, StartTimer, FailEvent, FailAsset, ModifierTreeId, Flags, "
- "EligibilityWorldStateID, EligibilityWorldStateValue FROM criteria ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_CRITERIA, "SELECT ID, Asset, StartAsset, FailAsset, StartTimer, ModifierTreeId, EligibilityWorldStateID, Type, "
+ "StartEvent, FailEvent, Flags, EligibilityWorldStateValue FROM criteria ORDER BY ID DESC", CONNECTION_SYNCH);
// CriteriaTree.db2
- PrepareStatement(HOTFIX_SEL_CRITERIA_TREE, "SELECT ID, CriteriaID, Amount, Operator, Parent, Flags, Description, OrderIndex FROM criteria_tree"
+ PrepareStatement(HOTFIX_SEL_CRITERIA_TREE, "SELECT ID, Amount, Description, CriteriaID, Parent, Flags, OrderIndex, Operator FROM criteria_tree"
" ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_CRITERIA_TREE, "SELECT ID, Description_lang FROM criteria_tree_locale WHERE locale = ?", CONNECTION_SYNCH);
// CurrencyTypes.db2
- PrepareStatement(HOTFIX_SEL_CURRENCY_TYPES, "SELECT ID, CategoryID, Name, InventoryIcon1, InventoryIcon2, SpellWeight, SpellCategory, MaxQty, "
- "MaxEarnablePerWeek, Flags, Quality, Description FROM currency_types ORDER BY ID DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMT(HOTFIX_SEL_CURRENCY_TYPES, "SELECT ID, Name_lang, InventoryIcon1_lang, InventoryIcon2_lang, Description_lang"
- " FROM currency_types_locale WHERE locale = ?", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_CURRENCY_TYPES, "SELECT ID, Name, InventoryIcon1, InventoryIcon2, MaxQty, MaxEarnablePerWeek, Flags, Description, "
+ "CategoryID, SpellWeight, SpellCategory, Quality FROM currency_types ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_CURRENCY_TYPES, "SELECT ID, Name_lang, Description_lang FROM currency_types_locale WHERE locale = ?", CONNECTION_SYNCH);
// CurvePoint.db2
- PrepareStatement(HOTFIX_SEL_CURVE_POINT, "SELECT ID, CurveID, `Index`, X, Y FROM curve_point ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_CURVE_POINT, "SELECT ID, X, Y, CurveID, `Index` FROM curve_point ORDER BY ID DESC", CONNECTION_SYNCH);
// DestructibleModelData.db2
- PrepareStatement(HOTFIX_SEL_DESTRUCTIBLE_MODEL_DATA, "SELECT ID, StateDamagedDisplayID, StateDamagedImpactEffectDoodadSet, "
- "StateDamagedAmbientDoodadSet, StateDamagedNameSet, StateDestroyedDisplayID, StateDestroyedDestructionDoodadSet, "
- "StateDestroyedImpactEffectDoodadSet, StateDestroyedAmbientDoodadSet, StateDestroyedNameSet, StateRebuildingDisplayID, "
+ PrepareStatement(HOTFIX_SEL_DESTRUCTIBLE_MODEL_DATA, "SELECT ID, StateDamagedDisplayID, StateDestroyedDisplayID, StateRebuildingDisplayID, "
+ "StateSmokeDisplayID, HealEffectSpeed, StateDamagedImpactEffectDoodadSet, StateDamagedAmbientDoodadSet, StateDamagedNameSet, "
+ "StateDestroyedDestructionDoodadSet, StateDestroyedImpactEffectDoodadSet, StateDestroyedAmbientDoodadSet, StateDestroyedNameSet, "
"StateRebuildingDestructionDoodadSet, StateRebuildingImpactEffectDoodadSet, StateRebuildingAmbientDoodadSet, StateRebuildingNameSet, "
- "StateSmokeDisplayID, StateSmokeInitDoodadSet, StateSmokeAmbientDoodadSet, StateSmokeNameSet, EjectDirection, RepairGroundFx, DoNotHighlight, "
- "HealEffect, HealEffectSpeed FROM destructible_model_data ORDER BY ID DESC", CONNECTION_SYNCH);
+ "StateSmokeInitDoodadSet, StateSmokeAmbientDoodadSet, StateSmokeNameSet, EjectDirection, DoNotHighlight, HealEffect"
+ " FROM destructible_model_data ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // DurabilityCosts.db2
+ PrepareStatement(HOTFIX_SEL_DURABILITY_COSTS, "SELECT ID, WeaponSubClassCost1, WeaponSubClassCost2, WeaponSubClassCost3, WeaponSubClassCost4, "
+ "WeaponSubClassCost5, WeaponSubClassCost6, WeaponSubClassCost7, WeaponSubClassCost8, WeaponSubClassCost9, WeaponSubClassCost10, "
+ "WeaponSubClassCost11, WeaponSubClassCost12, WeaponSubClassCost13, WeaponSubClassCost14, WeaponSubClassCost15, WeaponSubClassCost16, "
+ "WeaponSubClassCost17, WeaponSubClassCost18, WeaponSubClassCost19, WeaponSubClassCost20, WeaponSubClassCost21, ArmorSubClassCost1, "
+ "ArmorSubClassCost2, ArmorSubClassCost3, ArmorSubClassCost4, ArmorSubClassCost5, ArmorSubClassCost6, ArmorSubClassCost7, ArmorSubClassCost8"
+ " FROM durability_costs ORDER BY ID DESC", CONNECTION_SYNCH);
// DurabilityQuality.db2
PrepareStatement(HOTFIX_SEL_DURABILITY_QUALITY, "SELECT ID, QualityMod FROM durability_quality ORDER BY ID DESC", CONNECTION_SYNCH);
+ // EmotesTextSound.db2
+ PrepareStatement(HOTFIX_SEL_EMOTES_TEXT_SOUND, "SELECT ID, EmotesTextId, SoundId, RaceId, SexId, ClassId FROM emotes_text_sound ORDER BY ID DESC", CONNECTION_SYNCH);
+
// Gameobjects.db2
- PrepareStatement(HOTFIX_SEL_GAMEOBJECTS, "SELECT ID, MapID, DisplayID, PositionX, PositionY, PositionZ, RotationX, RotationY, RotationZ, "
- "RotationW, Size, PhaseUseFlags, PhaseID, PhaseGroupID, Type, Data1, Data2, Data3, Data4, Data5, Data6, Data7, Data8, Name FROM gameobjects"
+ PrepareStatement(HOTFIX_SEL_GAMEOBJECTS, "SELECT ID, PositionX, PositionY, PositionZ, RotationX, RotationY, RotationZ, RotationW, Size, Data1, "
+ "Data2, Data3, Data4, Data5, Data6, Data7, Data8, Name, MapID, DisplayID, PhaseID, PhaseGroupID, PhaseUseFlags, Type FROM gameobjects"
" ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_GAMEOBJECTS, "SELECT ID, Name_lang FROM gameobjects_locale WHERE locale = ?", CONNECTION_SYNCH);
+ // GameobjectDisplayInfo.db2
+ PrepareStatement(HOTFIX_SEL_GAMEOBJECT_DISPLAY_INFO, "SELECT ID, FileDataID, GeoBoxMinX, GeoBoxMinY, GeoBoxMinZ, GeoBoxMaxX, GeoBoxMaxY, "
+ "GeoBoxMaxZ, OverrideLootEffectScale, OverrideNameScale, Sound1, Sound2, Sound3, Sound4, Sound5, Sound6, Sound7, Sound8, Sound9, Sound10, "
+ "ObjectEffectPackageID FROM gameobject_display_info ORDER BY ID DESC", CONNECTION_SYNCH);
+
// GameTables.db2
PrepareStatement(HOTFIX_SEL_GAME_TABLES, "SELECT ID, Name, NumRows, NumColumns FROM game_tables ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_GAME_TABLES, "SELECT ID, Name_lang FROM game_tables_locale WHERE locale = ?", CONNECTION_SYNCH);
// GarrAbility.db2
- PrepareStatement(HOTFIX_SEL_GARR_ABILITY, "SELECT ID, Flags, Name, Description, IconFileDataID, OtherFactionGarrAbilityID, GarrAbilityCategoryID, "
+ PrepareStatement(HOTFIX_SEL_GARR_ABILITY, "SELECT ID, Name, Description, IconFileDataID, OtherFactionGarrAbilityID, Flags, GarrAbilityCategoryID, "
"FollowerTypeID FROM garr_ability ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_ABILITY, "SELECT ID, Name_lang, Description_lang FROM garr_ability_locale WHERE locale = ?", CONNECTION_SYNCH);
// GarrBuilding.db2
- PrepareStatement(HOTFIX_SEL_GARR_BUILDING, "SELECT ID, HordeGameObjectID, AllianceGameObjectID, Unknown, Type, Level, NameAlliance, NameHorde, "
- "Description, Tooltip, BuildDuration, CostCurrencyID, CostCurrencyAmount, HordeTexPrefixKitID, AllianceTexPrefixKitID, IconFileDataID, "
- "BonusAmount, Flags, AllianceActivationScenePackageID, HordeActivationScenePackageID, MaxShipments, FollowerRequiredGarrAbilityID, "
- "FollowerGarrAbilityEffectID, CostMoney FROM garr_building ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_GARR_BUILDING, "SELECT ID, HordeGameObjectID, AllianceGameObjectID, NameAlliance, NameHorde, Description, Tooltip, "
+ "IconFileDataID, BuildDuration, CostCurrencyID, CostCurrencyAmount, AllianceActivationScenePackageID, HordeActivationScenePackageID, "
+ "CostMoney, Unknown, Type, Level, HordeTexPrefixKitID, AllianceTexPrefixKitID, BonusAmount, Flags, MaxShipments, "
+ "FollowerRequiredGarrAbilityID, FollowerGarrAbilityEffectID, GarrTypeID FROM garr_building ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_BUILDING, "SELECT ID, NameAlliance_lang, NameHorde_lang, Description_lang, Tooltip_lang"
" FROM garr_building_locale WHERE locale = ?", CONNECTION_SYNCH);
// GarrBuildingPlotInst.db2
- PrepareStatement(HOTFIX_SEL_GARR_BUILDING_PLOT_INST, "SELECT ID, GarrBuildingID, UiTextureAtlasMemberID, GarrSiteLevelPlotInstID, "
- "LandmarkOffsetX, LandmarkOffsetY FROM garr_building_plot_inst ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_GARR_BUILDING_PLOT_INST, "SELECT ID, LandmarkOffsetX, LandmarkOffsetY, UiTextureAtlasMemberID, "
+ "GarrSiteLevelPlotInstID, GarrBuildingID FROM garr_building_plot_inst ORDER BY ID DESC", CONNECTION_SYNCH);
// GarrClassSpec.db2
PrepareStatement(HOTFIX_SEL_GARR_CLASS_SPEC, "SELECT ID, NameMale, NameFemale, NameGenderless, ClassAtlasID, GarrFollItemSetID"
@@ -153,10 +191,11 @@ void HotfixDatabaseConnection::DoPrepareStatements()
" WHERE locale = ?", CONNECTION_SYNCH);
// GarrFollower.db2
- PrepareStatement(HOTFIX_SEL_GARR_FOLLOWER, "SELECT ID, FollowerTypeID, HordeCreatureID, AllianceCreatureID, HordeUiAnimRaceInfoID, "
+ PrepareStatement(HOTFIX_SEL_GARR_FOLLOWER, "SELECT ID, HordeCreatureID, AllianceCreatureID, HordeSourceText, AllianceSourceText, "
+ "HordePortraitIconID, AlliancePortraitIconID, ItemLevelWeapon, ItemLevelArmor, FollowerTypeID, HordeUiAnimRaceInfoID, "
"AllianceUiAnimRaceInfoID, Quality, HordeGarrClassSpecID, AllianceGarrClassSpecID, HordeGarrFollItemSetID, AllianceGarrFollItemSetID, Level, "
- "ItemLevelWeapon, ItemLevelArmor, Unknown1, Flags, HordeSourceText, AllianceSourceText, Unknown2, Unknown3, HordePortraitIconID, "
- "AlliancePortraitIconID, HordeListPortraitTextureKitID, AllianceListPortraitTextureKitID FROM garr_follower ORDER BY ID DESC", CONNECTION_SYNCH);
+ "Unknown1, Flags, Unknown2, Unknown3, HordeListPortraitTextureKitID, AllianceListPortraitTextureKitID, GarrTypeID FROM garr_follower"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_FOLLOWER, "SELECT ID, HordeSourceText_lang, AllianceSourceText_lang FROM garr_follower_locale WHERE locale = ?", CONNECTION_SYNCH);
// GarrFollowerXAbility.db2
@@ -164,43 +203,51 @@ void HotfixDatabaseConnection::DoPrepareStatements()
" ORDER BY ID DESC", CONNECTION_SYNCH);
// GarrPlot.db2
- PrepareStatement(HOTFIX_SEL_GARR_PLOT, "SELECT ID, GarrPlotUICategoryID, PlotType, Flags, Name, MinCount, MaxCount, "
- "AllianceConstructionGameObjectID, HordeConstructionGameObjectID FROM garr_plot ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_GARR_PLOT, "SELECT ID, Name, AllianceConstructionGameObjectID, HordeConstructionGameObjectID, GarrPlotUICategoryID, "
+ "PlotType, Flags, MinCount, MaxCount FROM garr_plot ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_PLOT, "SELECT ID, Name_lang FROM garr_plot_locale WHERE locale = ?", CONNECTION_SYNCH);
// GarrPlotBuilding.db2
PrepareStatement(HOTFIX_SEL_GARR_PLOT_BUILDING, "SELECT ID, GarrPlotID, GarrBuildingID FROM garr_plot_building ORDER BY ID DESC", CONNECTION_SYNCH);
// GarrPlotInstance.db2
- PrepareStatement(HOTFIX_SEL_GARR_PLOT_INSTANCE, "SELECT ID, GarrPlotID, Name FROM garr_plot_instance ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_GARR_PLOT_INSTANCE, "SELECT ID, Name, GarrPlotID FROM garr_plot_instance ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_GARR_PLOT_INSTANCE, "SELECT ID, Name_lang FROM garr_plot_instance_locale WHERE locale = ?", CONNECTION_SYNCH);
// GarrSiteLevel.db2
- PrepareStatement(HOTFIX_SEL_GARR_SITE_LEVEL, "SELECT ID, Level, MapID, SiteID, UITextureKitID, TownHallX, TownHallY, MovieID, Level2, "
- "UpgradeResourceCost, UpgradeMoneyCost FROM garr_site_level ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_GARR_SITE_LEVEL, "SELECT ID, TownHallX, TownHallY, MapID, UpgradeResourceCost, UpgradeMoneyCost, Level, SiteID, "
+ "UITextureKitID, MovieID, Level2 FROM garr_site_level ORDER BY ID DESC", CONNECTION_SYNCH);
// GarrSiteLevelPlotInst.db2
- PrepareStatement(HOTFIX_SEL_GARR_SITE_LEVEL_PLOT_INST, "SELECT ID, GarrSiteLevelID, GarrPlotInstanceID, LandmarkX, LandmarkY, Unknown"
+ PrepareStatement(HOTFIX_SEL_GARR_SITE_LEVEL_PLOT_INST, "SELECT ID, LandmarkX, LandmarkY, GarrSiteLevelID, GarrPlotInstanceID, Unknown"
" FROM garr_site_level_plot_inst ORDER BY ID DESC", CONNECTION_SYNCH);
// GlyphSlot.db2
PrepareStatement(HOTFIX_SEL_GLYPH_SLOT, "SELECT ID, Type, Tooltip FROM glyph_slot ORDER BY ID DESC", CONNECTION_SYNCH);
+ // GuildColorBackground.db2
+ PrepareStatement(HOTFIX_SEL_GUILD_COLOR_BACKGROUND, "SELECT ID, Red, Green, Blue FROM guild_color_background ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // GuildColorBorder.db2
+ PrepareStatement(HOTFIX_SEL_GUILD_COLOR_BORDER, "SELECT ID, Red, Green, Blue FROM guild_color_border ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // GuildColorEmblem.db2
+ PrepareStatement(HOTFIX_SEL_GUILD_COLOR_EMBLEM, "SELECT ID, Red, Green, Blue FROM guild_color_emblem ORDER BY ID DESC", CONNECTION_SYNCH);
+
// GuildPerkSpells.db2
- PrepareStatement(HOTFIX_SEL_GUILD_PERK_SPELLS, "SELECT ID, GuildLevel, SpellID FROM guild_perk_spells ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_GUILD_PERK_SPELLS, "SELECT ID, SpellID, GuildLevel FROM guild_perk_spells ORDER BY ID DESC", CONNECTION_SYNCH);
// Heirloom.db2
- PrepareStatement(HOTFIX_SEL_HEIRLOOM, "SELECT ID, ItemID, Flags, SourceText, Source, OldItem1, OldItem2, NextDifficultyItemID, UpgradeItemID1, "
- "UpgradeItemID2, ItemBonusListID1, ItemBonusListID2 FROM heirloom ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_HEIRLOOM, "SELECT ID, ItemID, SourceText, OldItem1, OldItem2, NextDifficultyItemID, UpgradeItemID1, UpgradeItemID2, "
+ "ItemBonusListID1, ItemBonusListID2, Flags, Source FROM heirloom ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_HEIRLOOM, "SELECT ID, SourceText_lang FROM heirloom_locale WHERE locale = ?", CONNECTION_SYNCH);
// Holidays.db2
- PrepareStatement(HOTFIX_SEL_HOLIDAYS, "SELECT ID, Duration1, Duration2, Duration3, Duration4, Duration5, Duration6, Duration7, Duration8, "
- "Duration9, Duration10, Date1, Date2, Date3, Date4, Date5, Date6, Date7, Date8, Date9, Date10, Date11, Date12, Date13, Date14, Date15, "
- "Date16, Region, Looping, CalendarFlags1, CalendarFlags2, CalendarFlags3, CalendarFlags4, CalendarFlags5, CalendarFlags6, CalendarFlags7, "
- "CalendarFlags8, CalendarFlags9, CalendarFlags10, HolidayNameID, HolidayDescriptionID, TextureFilename, Priority, CalendarFilterType, Flags"
- " FROM holidays ORDER BY ID DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMT(HOTFIX_SEL_HOLIDAYS, "SELECT ID, TextureFilename_lang FROM holidays_locale WHERE locale = ?", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_HOLIDAYS, "SELECT ID, Date1, Date2, Date3, Date4, Date5, Date6, Date7, Date8, Date9, Date10, Date11, Date12, Date13, "
+ "Date14, Date15, Date16, TextureFilename, Duration1, Duration2, Duration3, Duration4, Duration5, Duration6, Duration7, Duration8, Duration9, "
+ "Duration10, Region, Looping, CalendarFlags1, CalendarFlags2, CalendarFlags3, CalendarFlags4, CalendarFlags5, CalendarFlags6, CalendarFlags7, "
+ "CalendarFlags8, CalendarFlags9, CalendarFlags10, HolidayNameID, HolidayDescriptionID, Priority, CalendarFilterType, Flags FROM holidays"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
// ImportPriceArmor.db2
PrepareStatement(HOTFIX_SEL_IMPORT_PRICE_ARMOR, "SELECT ID, ClothFactor, LeatherFactor, MailFactor, PlateFactor FROM import_price_armor"
@@ -215,83 +262,120 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// ImportPriceWeapon.db2
PrepareStatement(HOTFIX_SEL_IMPORT_PRICE_WEAPON, "SELECT ID, Factor FROM import_price_weapon ORDER BY ID DESC", CONNECTION_SYNCH);
+ // Item.db2
+ PrepareStatement(HOTFIX_SEL_ITEM, "SELECT ID, FileDataID, Class, SubClass, SoundOverrideSubclass, Material, InventoryType, Sheath, GroupSoundsID"
+ " FROM item ORDER BY ID DESC", CONNECTION_SYNCH);
+
// ItemAppearance.db2
- PrepareStatement(HOTFIX_SEL_ITEM_APPEARANCE, "SELECT ID, DisplayID, IconFileDataID FROM item_appearance ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_APPEARANCE, "SELECT ID, DisplayID, IconFileDataID, ObjectComponentSlot FROM item_appearance ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemArmorQuality.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_ARMOR_QUALITY, "SELECT ID, QualityMod1, QualityMod2, QualityMod3, QualityMod4, QualityMod5, QualityMod6, "
+ "QualityMod7, ItemLevel FROM item_armor_quality ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemArmorShield.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_ARMOR_SHIELD, "SELECT ID, Quality1, Quality2, Quality3, Quality4, Quality5, Quality6, Quality7, ItemLevel"
+ " FROM item_armor_shield ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemArmorTotal.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_ARMOR_TOTAL, "SELECT ID, Value1, Value2, Value3, Value4, ItemLevel FROM item_armor_total ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemBagFamily.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_BAG_FAMILY, "SELECT ID, Name FROM item_bag_family ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_BAG_FAMILY, "SELECT ID, Name_lang FROM item_bag_family_locale WHERE locale = ?", CONNECTION_SYNCH);
// ItemBonus.db2
- PrepareStatement(HOTFIX_SEL_ITEM_BONUS, "SELECT ID, BonusListID, Type, Value1, Value2, `Index` FROM item_bonus ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_BONUS, "SELECT ID, Value1, Value2, BonusListID, Type, `Index` FROM item_bonus ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemBonusTreeNode.db2
- PrepareStatement(HOTFIX_SEL_ITEM_BONUS_TREE_NODE, "SELECT ID, BonusTreeID, BonusTreeModID, SubTreeID, BonusListID FROM item_bonus_tree_node"
+ PrepareStatement(HOTFIX_SEL_ITEM_BONUS_TREE_NODE, "SELECT ID, BonusTreeID, SubTreeID, BonusListID, BonusTreeModID FROM item_bonus_tree_node"
" ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemClass.db2
- PrepareStatement(HOTFIX_SEL_ITEM_CLASS, "SELECT ID, Flags, PriceMod, Name FROM item_class ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_CLASS, "SELECT ID, PriceMod, Name, Flags FROM item_class ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_CLASS, "SELECT ID, Name_lang FROM item_class_locale WHERE locale = ?", CONNECTION_SYNCH);
// ItemCurrencyCost.db2
PrepareStatement(HOTFIX_SEL_ITEM_CURRENCY_COST, "SELECT ID, ItemId FROM item_currency_cost ORDER BY ID DESC", CONNECTION_SYNCH);
+ // ItemDamageAmmo.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_DAMAGE_AMMO, "SELECT ID, DPS1, DPS2, DPS3, DPS4, DPS5, DPS6, DPS7, ItemLevel FROM item_damage_ammo"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemDamageOneHand.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_DAMAGE_ONE_HAND, "SELECT ID, DPS1, DPS2, DPS3, DPS4, DPS5, DPS6, DPS7, ItemLevel FROM item_damage_one_hand"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemDamageOneHandCaster.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_DAMAGE_ONE_HAND_CASTER, "SELECT ID, DPS1, DPS2, DPS3, DPS4, DPS5, DPS6, DPS7, ItemLevel"
+ " FROM item_damage_one_hand_caster ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemDamageTwoHand.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_DAMAGE_TWO_HAND, "SELECT ID, DPS1, DPS2, DPS3, DPS4, DPS5, DPS6, DPS7, ItemLevel FROM item_damage_two_hand"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // ItemDamageTwoHandCaster.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_DAMAGE_TWO_HAND_CASTER, "SELECT ID, DPS1, DPS2, DPS3, DPS4, DPS5, DPS6, DPS7, ItemLevel"
+ " FROM item_damage_two_hand_caster ORDER BY ID DESC", CONNECTION_SYNCH);
+
// ItemDisenchantLoot.db2
- PrepareStatement(HOTFIX_SEL_ITEM_DISENCHANT_LOOT, "SELECT ID, ItemClass, ItemSubClass, ItemQuality, MinItemLevel, MaxItemLevel, "
- "RequiredDisenchantSkill FROM item_disenchant_loot ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_DISENCHANT_LOOT, "SELECT ID, MinItemLevel, MaxItemLevel, RequiredDisenchantSkill, ItemClass, ItemSubClass, "
+ "ItemQuality FROM item_disenchant_loot ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemEffect.db2
- PrepareStatement(HOTFIX_SEL_ITEM_EFFECT, "SELECT ID, ItemID, OrderIndex, SpellID, `Trigger`, Charges, Cooldown, Category, CategoryCooldown, "
- "ChrSpecializationID FROM item_effect ORDER BY ID DESC", CONNECTION_SYNCH);
-
- // Item.db2
- PrepareStatement(HOTFIX_SEL_ITEM, "SELECT ID, Class, SubClass, SoundOverrideSubclass, Material, InventoryType, Sheath, FileDataID, GroupSoundsID"
- " FROM item ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_EFFECT, "SELECT ID, ItemID, SpellID, Cooldown, CategoryCooldown, Charges, Category, ChrSpecializationID, "
+ "OrderIndex, `Trigger` FROM item_effect ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemExtendedCost.db2
- PrepareStatement(HOTFIX_SEL_ITEM_EXTENDED_COST, "SELECT ID, RequiredArenaSlot, RequiredItem1, RequiredItem2, RequiredItem3, RequiredItem4, "
- "RequiredItem5, RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, "
- "RequiredPersonalArenaRating, ItemPurchaseGroup, RequiredCurrency1, RequiredCurrency2, RequiredCurrency3, RequiredCurrency4, "
- "RequiredCurrency5, RequiredCurrencyCount1, RequiredCurrencyCount2, RequiredCurrencyCount3, RequiredCurrencyCount4, RequiredCurrencyCount5, "
- "RequiredFactionId, RequiredFactionStanding, RequirementFlags, RequiredAchievement, RequiredMoney FROM item_extended_cost ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_EXTENDED_COST, "SELECT ID, RequiredItem1, RequiredItem2, RequiredItem3, RequiredItem4, RequiredItem5, "
+ "RequiredCurrencyCount1, RequiredCurrencyCount2, RequiredCurrencyCount3, RequiredCurrencyCount4, RequiredCurrencyCount5, RequiredMoney, "
+ "RequiredItemCount1, RequiredItemCount2, RequiredItemCount3, RequiredItemCount4, RequiredItemCount5, RequiredPersonalArenaRating, "
+ "RequiredCurrency1, RequiredCurrency2, RequiredCurrency3, RequiredCurrency4, RequiredCurrency5, RequiredArenaSlot, RequiredFactionId, "
+ "RequiredFactionStanding, RequirementFlags, RequiredAchievement FROM item_extended_cost ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemLimitCategory.db2
PrepareStatement(HOTFIX_SEL_ITEM_LIMIT_CATEGORY, "SELECT ID, Name, Quantity, Flags FROM item_limit_category ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_LIMIT_CATEGORY, "SELECT ID, Name_lang FROM item_limit_category_locale WHERE locale = ?", CONNECTION_SYNCH);
// ItemModifiedAppearance.db2
- PrepareStatement(HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE, "SELECT ID, ItemID, AppearanceModID, AppearanceID, IconFileDataID, `Index`"
- " FROM item_modified_appearance ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_MODIFIED_APPEARANCE, "SELECT ID, ItemID, AppearanceID, AppearanceModID, `Index` FROM item_modified_appearance"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemPriceBase.db2
- PrepareStatement(HOTFIX_SEL_ITEM_PRICE_BASE, "SELECT ID, ItemLevel, ArmorFactor, WeaponFactor FROM item_price_base ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_PRICE_BASE, "SELECT ID, ArmorFactor, WeaponFactor, ItemLevel FROM item_price_base ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemRandomProperties.db2
- PrepareStatement(HOTFIX_SEL_ITEM_RANDOM_PROPERTIES, "SELECT ID, InternalName, Enchantment1, Enchantment2, Enchantment3, Enchantment4, "
- "Enchantment5, Name FROM item_random_properties ORDER BY ID DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_RANDOM_PROPERTIES, "SELECT ID, InternalName_lang, Name_lang FROM item_random_properties_locale"
- " WHERE locale = ?", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_ITEM_RANDOM_PROPERTIES, "SELECT ID, Name, Enchantment1, Enchantment2, Enchantment3, Enchantment4, Enchantment5"
+ " FROM item_random_properties ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_RANDOM_PROPERTIES, "SELECT ID, Name_lang FROM item_random_properties_locale WHERE locale = ?", CONNECTION_SYNCH);
// ItemRandomSuffix.db2
PrepareStatement(HOTFIX_SEL_ITEM_RANDOM_SUFFIX, "SELECT ID, Name, InternalName, Enchantment1, Enchantment2, Enchantment3, Enchantment4, "
"Enchantment5, AllocationPct1, AllocationPct2, AllocationPct3, AllocationPct4, AllocationPct5 FROM item_random_suffix ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_RANDOM_SUFFIX, "SELECT ID, Name_lang, InternalName_lang FROM item_random_suffix_locale WHERE locale = ?", CONNECTION_SYNCH);
+ // ItemSetSpell.db2
+ PrepareStatement(HOTFIX_SEL_ITEM_SET_SPELL, "SELECT ID, SpellID, ItemSetID, ChrSpecID, Threshold FROM item_set_spell ORDER BY ID DESC", CONNECTION_SYNCH);
+
// ItemSparse.db2
- PrepareStatement(HOTFIX_SEL_ITEM_SPARSE, "SELECT ID, Quality, Flags1, Flags2, Flags3, Unk1, Unk2, BuyCount, BuyPrice, SellPrice, InventoryType, "
- "AllowableClass, AllowableRace, ItemLevel, RequiredLevel, RequiredSkill, RequiredSkillRank, RequiredSpell, RequiredHonorRank, "
- "RequiredCityRank, RequiredReputationFaction, RequiredReputationRank, MaxCount, Stackable, ContainerSlots, ItemStatType1, ItemStatType2, "
- "ItemStatType3, ItemStatType4, ItemStatType5, ItemStatType6, ItemStatType7, ItemStatType8, ItemStatType9, ItemStatType10, ItemStatValue1, "
- "ItemStatValue2, ItemStatValue3, ItemStatValue4, ItemStatValue5, ItemStatValue6, ItemStatValue7, ItemStatValue8, ItemStatValue9, "
- "ItemStatValue10, ItemStatAllocation1, ItemStatAllocation2, ItemStatAllocation3, ItemStatAllocation4, ItemStatAllocation5, "
+ PrepareStatement(HOTFIX_SEL_ITEM_SPARSE, "SELECT ID, Flags1, Flags2, Flags3, Unk1, Unk2, BuyPrice, SellPrice, AllowableClass, AllowableRace, "
+ "RequiredSpell, MaxCount, Stackable, ItemStatAllocation1, ItemStatAllocation2, ItemStatAllocation3, ItemStatAllocation4, ItemStatAllocation5, "
"ItemStatAllocation6, ItemStatAllocation7, ItemStatAllocation8, ItemStatAllocation9, ItemStatAllocation10, ItemStatSocketCostMultiplier1, "
"ItemStatSocketCostMultiplier2, ItemStatSocketCostMultiplier3, ItemStatSocketCostMultiplier4, ItemStatSocketCostMultiplier5, "
"ItemStatSocketCostMultiplier6, ItemStatSocketCostMultiplier7, ItemStatSocketCostMultiplier8, ItemStatSocketCostMultiplier9, "
- "ItemStatSocketCostMultiplier10, ScalingStatDistribution, DamageType, Delay, RangedModRange, Bonding, Name, Name2, Name3, Name4, Description, "
- "PageText, LanguageID, PageMaterial, StartQuest, LockID, Material, Sheath, RandomProperty, RandomSuffix, ItemSet, Area, Map, BagFamily, "
- "TotemCategory, SocketColor1, SocketColor2, SocketColor3, SocketBonus, GemProperties, ArmorDamageModifier, Duration, ItemLimitCategory, "
- "HolidayID, StatScalingFactor, CurrencySubstitutionID, CurrencySubstitutionCount, ItemNameDescriptionID FROM item_sparse ORDER BY ID DESC", CONNECTION_SYNCH);
+ "ItemStatSocketCostMultiplier10, RangedModRange, Name, Name2, Name3, Name4, Description, BagFamily, ArmorDamageModifier, Duration, "
+ "StatScalingFactor, ItemLevel, RequiredSkill, RequiredSkillRank, RequiredReputationFaction, ItemStatValue1, ItemStatValue2, ItemStatValue3, "
+ "ItemStatValue4, ItemStatValue5, ItemStatValue6, ItemStatValue7, ItemStatValue8, ItemStatValue9, ItemStatValue10, ScalingStatDistribution, "
+ "Delay, PageText, StartQuest, LockID, RandomProperty, RandomSuffix, ItemSet, Area, Map, SocketBonus, GemProperties, ItemLimitCategory, "
+ "HolidayID, ItemNameDescriptionID, Quality, BuyCount, InventoryType, RequiredLevel, RequiredHonorRank, RequiredCityRank, "
+ "RequiredReputationRank, ContainerSlots, ItemStatType1, ItemStatType2, ItemStatType3, ItemStatType4, ItemStatType5, ItemStatType6, "
+ "ItemStatType7, ItemStatType8, ItemStatType9, ItemStatType10, DamageType, Bonding, LanguageID, PageMaterial, Material, Sheath, TotemCategory, "
+ "SocketColor1, SocketColor2, SocketColor3, CurrencySubstitutionID, CurrencySubstitutionCount, ArtifactID FROM item_sparse ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_ITEM_SPARSE, "SELECT ID, Name_lang, Name2_lang, Name3_lang, Name4_lang, Description_lang FROM item_sparse_locale"
" WHERE locale = ?", CONNECTION_SYNCH);
// ItemSpec.db2
- PrepareStatement(HOTFIX_SEL_ITEM_SPEC, "SELECT ID, MinLevel, MaxLevel, ItemType, PrimaryStat, SecondaryStat, SpecID FROM item_spec"
+ PrepareStatement(HOTFIX_SEL_ITEM_SPEC, "SELECT ID, SpecID, MinLevel, MaxLevel, ItemType, PrimaryStat, SecondaryStat FROM item_spec"
" ORDER BY ID DESC", CONNECTION_SYNCH);
// ItemSpecOverride.db2
@@ -304,30 +388,33 @@ void HotfixDatabaseConnection::DoPrepareStatements()
PrepareStatement(HOTFIX_SEL_ITEM_X_BONUS_TREE, "SELECT ID, ItemID, BonusTreeID FROM item_x_bonus_tree ORDER BY ID DESC", CONNECTION_SYNCH);
// KeyChain.db2
- PrepareStatement(HOTFIX_SEL_KEY_CHAIN, "SELECT Id, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8, Key9, Key10, Key11, Key12, Key13, Key14, "
+ PrepareStatement(HOTFIX_SEL_KEY_CHAIN, "SELECT ID, Key1, Key2, Key3, Key4, Key5, Key6, Key7, Key8, Key9, Key10, Key11, Key12, Key13, Key14, "
"Key15, Key16, Key17, Key18, Key19, Key20, Key21, Key22, Key23, Key24, Key25, Key26, Key27, Key28, Key29, Key30, Key31, Key32 FROM key_chain"
- " ORDER BY Id DESC", CONNECTION_SYNCH);
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
// MailTemplate.db2
PrepareStatement(HOTFIX_SEL_MAIL_TEMPLATE, "SELECT ID, Body FROM mail_template ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_MAIL_TEMPLATE, "SELECT ID, Body_lang FROM mail_template_locale WHERE locale = ?", CONNECTION_SYNCH);
// ModifierTree.db2
- PrepareStatement(HOTFIX_SEL_MODIFIER_TREE, "SELECT ID, Type, Asset1, Asset2, Operator, Amount, Parent FROM modifier_tree ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_MODIFIER_TREE, "SELECT ID, Asset1, Asset2, Parent, Type, Unk700, Operator, Amount FROM modifier_tree ORDER BY ID DESC", CONNECTION_SYNCH);
// Mount.db2
- PrepareStatement(HOTFIX_SEL_MOUNT, "SELECT Id, SpellId, MountTypeId, DisplayId, Flags, Name, Description, SourceDescription, Source, "
- "PlayerConditionId FROM mount ORDER BY Id DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMT(HOTFIX_SEL_MOUNT, "SELECT Id, Name_lang, Description_lang, SourceDescription_lang FROM mount_locale WHERE locale = ?", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_MOUNT, "SELECT ID, SpellId, DisplayId, Name, Description, SourceDescription, MountTypeId, Flags, PlayerConditionId, "
+ "Source FROM mount ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_MOUNT, "SELECT ID, Name_lang, Description_lang, SourceDescription_lang FROM mount_locale WHERE locale = ?", CONNECTION_SYNCH);
// MountCapability.db2
- PrepareStatement(HOTFIX_SEL_MOUNT_CAPABILITY, "SELECT ID, Flags, RequiredRidingSkill, RequiredArea, RequiredAura, RequiredSpell, SpeedModSpell, "
- "RequiredMap FROM mount_capability ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_MOUNT_CAPABILITY, "SELECT ID, RequiredSpell, SpeedModSpell, RequiredRidingSkill, RequiredArea, RequiredMap, Flags, "
+ "RequiredAura FROM mount_capability ORDER BY ID DESC", CONNECTION_SYNCH);
// MountTypeXCapability.db2
- PrepareStatement(HOTFIX_SEL_MOUNT_TYPE_X_CAPABILITY, "SELECT ID, MountTypeID, OrderIndex, MountCapabilityID FROM mount_type_x_capability"
+ PrepareStatement(HOTFIX_SEL_MOUNT_TYPE_X_CAPABILITY, "SELECT ID, MountTypeID, MountCapabilityID, OrderIndex FROM mount_type_x_capability"
" ORDER BY ID DESC", CONNECTION_SYNCH);
+ // Movie.db2
+ PrepareStatement(HOTFIX_SEL_MOVIE, "SELECT ID, AudioFileDataID, SubtitleFileDataID, Volume, KeyID FROM movie ORDER BY ID DESC", CONNECTION_SYNCH);
+
// NameGen.db2
PrepareStatement(HOTFIX_SEL_NAME_GEN, "SELECT ID, Name, Race, Sex FROM name_gen ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_NAME_GEN, "SELECT ID, Name_lang FROM name_gen_locale WHERE locale = ?", CONNECTION_SYNCH);
@@ -343,35 +430,44 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// OverrideSpellData.db2
PrepareStatement(HOTFIX_SEL_OVERRIDE_SPELL_DATA, "SELECT ID, SpellID1, SpellID2, SpellID3, SpellID4, SpellID5, SpellID6, SpellID7, SpellID8, "
- "SpellID9, SpellID10, Flags, PlayerActionbarFileDataID FROM override_spell_data ORDER BY ID DESC", CONNECTION_SYNCH);
+ "SpellID9, SpellID10, PlayerActionbarFileDataID, Flags FROM override_spell_data ORDER BY ID DESC", CONNECTION_SYNCH);
// PhaseXPhaseGroup.db2
PrepareStatement(HOTFIX_SEL_PHASE_X_PHASE_GROUP, "SELECT ID, PhaseID, PhaseGroupID FROM phase_x_phase_group ORDER BY ID DESC", CONNECTION_SYNCH);
// PlayerCondition.db2
- PrepareStatement(HOTFIX_SEL_PLAYER_CONDITION, "SELECT ID, Flags, MinLevel, MaxLevel, RaceMask, ClassMask, Gender, NativeGender, SkillID1, "
- "SkillID2, SkillID3, SkillID4, MinSkill1, MinSkill2, MinSkill3, MinSkill4, MaxSkill1, MaxSkill2, MaxSkill3, MaxSkill4, SkillLogic, "
- "LanguageID, MinLanguage, MaxLanguage, MinFactionID1, MinFactionID2, MinFactionID3, MaxFactionID, MinReputation1, MinReputation2, "
- "MinReputation3, MaxReputation, ReputationLogic, Unknown1, MinPVPRank, MaxPVPRank, PvpMedal, PrevQuestLogic, PrevQuestID1, PrevQuestID2, "
- "PrevQuestID3, PrevQuestID4, CurrQuestLogic, CurrQuestID1, CurrQuestID2, CurrQuestID3, CurrQuestID4, CurrentCompletedQuestLogic, "
- "CurrentCompletedQuestID1, CurrentCompletedQuestID2, CurrentCompletedQuestID3, CurrentCompletedQuestID4, SpellLogic, SpellID1, SpellID2, "
- "SpellID3, SpellID4, ItemLogic, ItemID1, ItemID2, ItemID3, ItemID4, ItemCount1, ItemCount2, ItemCount3, ItemCount4, ItemFlags, Explored1, "
- "Explored2, Time1, Time2, AuraSpellLogic, AuraSpellID1, AuraSpellID2, AuraSpellID3, AuraSpellID4, WorldStateExpressionID, WeatherID, "
- "PartyStatus, LifetimeMaxPVPRank, AchievementLogic, Achievement1, Achievement2, Achievement3, Achievement4, LfgLogic, LfgStatus1, LfgStatus2, "
- "LfgStatus3, LfgStatus4, LfgCompare1, LfgCompare2, LfgCompare3, LfgCompare4, LfgValue1, LfgValue2, LfgValue3, LfgValue4, AreaLogic, AreaID1, "
- "AreaID2, AreaID3, AreaID4, CurrencyLogic, CurrencyID1, CurrencyID2, CurrencyID3, CurrencyID4, CurrencyCount1, CurrencyCount2, "
- "CurrencyCount3, CurrencyCount4, QuestKillID, QuestKillLogic, QuestKillMonster1, QuestKillMonster2, QuestKillMonster3, QuestKillMonster4, "
- "MinExpansionLevel, MaxExpansionLevel, MinExpansionTier, MaxExpansionTier, MinGuildLevel, MaxGuildLevel, PhaseUseFlags, PhaseID, "
- "PhaseGroupID, MinAvgItemLevel, MaxAvgItemLevel, MinAvgEquippedItemLevel, MaxAvgEquippedItemLevel, ChrSpecializationIndex, "
- "ChrSpecializationRole, FailureDescription, PowerType, PowerTypeComp, PowerTypeValue FROM player_condition ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_PLAYER_CONDITION, "SELECT ID, RaceMask, SkillLogic, ReputationLogic, PrevQuestLogic, CurrQuestLogic, "
+ "CurrentCompletedQuestLogic, SpellLogic, SpellID1, SpellID2, SpellID3, SpellID4, ItemLogic, ItemID1, ItemID2, ItemID3, ItemID4, Time1, Time2, "
+ "AuraSpellLogic, AuraSpellID1, AuraSpellID2, AuraSpellID3, AuraSpellID4, AchievementLogic, AreaLogic, QuestKillLogic, QuestKillMonster1, "
+ "QuestKillMonster2, QuestKillMonster3, QuestKillMonster4, QuestKillMonster5, QuestKillMonster6, FailureDescription, Unknown700_1, "
+ "Unknown700_2, MinLevel, MaxLevel, ClassMask, SkillID1, SkillID2, SkillID3, SkillID4, MinSkill1, MinSkill2, MinSkill3, MinSkill4, MaxSkill1, "
+ "MaxSkill2, MaxSkill3, MaxSkill4, MinFactionID1, MinFactionID2, MinFactionID3, MaxFactionID, PrevQuestID1, PrevQuestID2, PrevQuestID3, "
+ "PrevQuestID4, CurrQuestID1, CurrQuestID2, CurrQuestID3, CurrQuestID4, CurrentCompletedQuestID1, CurrentCompletedQuestID2, "
+ "CurrentCompletedQuestID3, CurrentCompletedQuestID4, Explored1, Explored2, WorldStateExpressionID, Achievement1, Achievement2, Achievement3, "
+ "Achievement4, AreaID1, AreaID2, AreaID3, AreaID4, QuestKillID, PhaseID, MinAvgItemLevel, MaxAvgItemLevel, MinAvgEquippedItemLevel, "
+ "MaxAvgEquippedItemLevel, ModifierTreeID, Flags, Gender, NativeGender, LanguageID, MinLanguage, MaxLanguage, MinReputation1, MinReputation2, "
+ "MinReputation3, MaxReputation, Unknown1, MinPVPRank, MaxPVPRank, PvpMedal, ItemCount1, ItemCount2, ItemCount3, ItemCount4, ItemFlags, "
+ "AuraCount1, AuraCount2, AuraCount3, AuraCount4, WeatherID, PartyStatus, LifetimeMaxPVPRank, LfgLogic, LfgStatus1, LfgStatus2, LfgStatus3, "
+ "LfgStatus4, LfgCompare1, LfgCompare2, LfgCompare3, LfgCompare4, LfgValue1, LfgValue2, LfgValue3, LfgValue4, CurrencyLogic, CurrencyID1, "
+ "CurrencyID2, CurrencyID3, CurrencyID4, CurrencyCount1, CurrencyCount2, CurrencyCount3, CurrencyCount4, MinExpansionLevel, MaxExpansionLevel, "
+ "MinExpansionTier, MaxExpansionTier, MinGuildLevel, MaxGuildLevel, PhaseUseFlags, PhaseGroupID, ChrSpecializationIndex, "
+ "ChrSpecializationRole, PowerType, PowerTypeComp, PowerTypeValue FROM player_condition ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_PLAYER_CONDITION, "SELECT ID, FailureDescription_lang FROM player_condition_locale WHERE locale = ?", CONNECTION_SYNCH);
+ // PowerDisplay.db2
+ PrepareStatement(HOTFIX_SEL_POWER_DISPLAY, "SELECT ID, GlobalStringBaseTag, PowerType, Red, Green, Blue FROM power_display ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // QuestFactionReward.db2
+ PrepareStatement(HOTFIX_SEL_QUEST_FACTION_REWARD, "SELECT ID, QuestRewFactionValue1, QuestRewFactionValue2, QuestRewFactionValue3, "
+ "QuestRewFactionValue4, QuestRewFactionValue5, QuestRewFactionValue6, QuestRewFactionValue7, QuestRewFactionValue8, QuestRewFactionValue9, "
+ "QuestRewFactionValue10 FROM quest_faction_reward ORDER BY ID DESC", CONNECTION_SYNCH);
+
// QuestMoneyReward.db2
- PrepareStatement(HOTFIX_SEL_QUEST_MONEY_REWARD, "SELECT Level, Money1, Money2, Money3, Money4, Money5, Money6, Money7, Money8, Money9, Money10"
- " FROM quest_money_reward ORDER BY Level DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_QUEST_MONEY_REWARD, "SELECT ID, Money1, Money2, Money3, Money4, Money5, Money6, Money7, Money8, Money9, Money10"
+ " FROM quest_money_reward ORDER BY ID DESC", CONNECTION_SYNCH);
// QuestPackageItem.db2
- PrepareStatement(HOTFIX_SEL_QUEST_PACKAGE_ITEM, "SELECT ID, QuestPackageID, ItemID, ItemCount, FilterType FROM quest_package_item ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_QUEST_PACKAGE_ITEM, "SELECT ID, ItemID, QuestPackageID, ItemCount, FilterType FROM quest_package_item ORDER BY ID DESC", CONNECTION_SYNCH);
// QuestSort.db2
PrepareStatement(HOTFIX_SEL_QUEST_SORT, "SELECT ID, SortName FROM quest_sort ORDER BY ID DESC", CONNECTION_SYNCH);
@@ -383,42 +479,106 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// QuestXp.db2
PrepareStatement(HOTFIX_SEL_QUEST_XP, "SELECT ID, Exp1, Exp2, Exp3, Exp4, Exp5, Exp6, Exp7, Exp8, Exp9, Exp10 FROM quest_xp ORDER BY ID DESC", CONNECTION_SYNCH);
+ // RandPropPoints.db2
+ PrepareStatement(HOTFIX_SEL_RAND_PROP_POINTS, "SELECT ID, EpicPropertiesPoints1, EpicPropertiesPoints2, EpicPropertiesPoints3, "
+ "EpicPropertiesPoints4, EpicPropertiesPoints5, RarePropertiesPoints1, RarePropertiesPoints2, RarePropertiesPoints3, RarePropertiesPoints4, "
+ "RarePropertiesPoints5, UncommonPropertiesPoints1, UncommonPropertiesPoints2, UncommonPropertiesPoints3, UncommonPropertiesPoints4, "
+ "UncommonPropertiesPoints5 FROM rand_prop_points ORDER BY ID DESC", CONNECTION_SYNCH);
+
// ScalingStatDistribution.db2
- PrepareStatement(HOTFIX_SEL_SCALING_STAT_DISTRIBUTION, "SELECT ID, MinLevel, MaxLevel, ItemLevelCurveID FROM scaling_stat_distribution"
+ PrepareStatement(HOTFIX_SEL_SCALING_STAT_DISTRIBUTION, "SELECT ID, ItemLevelCurveID, MinLevel, MaxLevel FROM scaling_stat_distribution"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SkillLine.db2
+ PrepareStatement(HOTFIX_SEL_SKILL_LINE, "SELECT ID, DisplayName, Description, AlternateVerb, SpellIconID, Flags, CategoryID, CanLink, "
+ "ParentSkillLineID FROM skill_line ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_SKILL_LINE, "SELECT ID, DisplayName_lang, Description_lang, AlternateVerb_lang FROM skill_line_locale"
+ " WHERE locale = ?", CONNECTION_SYNCH);
+
+ // SkillLineAbility.db2
+ PrepareStatement(HOTFIX_SEL_SKILL_LINE_ABILITY, "SELECT ID, SpellID, RaceMask, ClassMask, SupercedesSpell, SkillLine, MinSkillLineRank, "
+ "TrivialSkillLineRankHigh, TrivialSkillLineRankLow, UniqueBit, TradeSkillCategoryID, AquireMethod, NumSkillUps FROM skill_line_ability"
" ORDER BY ID DESC", CONNECTION_SYNCH);
- // SoundEntries.db2
- PrepareStatement(HOTFIX_SEL_SOUND_ENTRIES, "SELECT ID, SoundType, Name, FileDataID1, FileDataID2, FileDataID3, FileDataID4, FileDataID5, "
- "FileDataID6, FileDataID7, FileDataID8, FileDataID9, FileDataID10, FileDataID11, FileDataID12, FileDataID13, FileDataID14, FileDataID15, "
- "FileDataID16, FileDataID17, FileDataID18, FileDataID19, FileDataID20, Freq1, Freq2, Freq3, Freq4, Freq5, Freq6, Freq7, Freq8, Freq9, Freq10, "
- "Freq11, Freq12, Freq13, Freq14, Freq15, Freq16, Freq17, Freq18, Freq19, Freq20, VolumeFloat, Flags, MinDistance, DistanceCutoff, EAXDef, "
- "SoundEntriesAdvancedID, VolumeVariationPlus, VolumeVariationMinus, PitchVariationPlus, PitchVariationMinus, PitchAdjust, DialogType, "
- "BusOverwriteID FROM sound_entries ORDER BY ID DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMT(HOTFIX_SEL_SOUND_ENTRIES, "SELECT ID, Name_lang FROM sound_entries_locale WHERE locale = ?", CONNECTION_SYNCH);
+ // SkillRaceClassInfo.db2
+ PrepareStatement(HOTFIX_SEL_SKILL_RACE_CLASS_INFO, "SELECT ID, RaceMask, SkillID, ClassMask, Flags, SkillTierID, Availability, MinLevel"
+ " FROM skill_race_class_info ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SoundKit.db2
+ PrepareStatement(HOTFIX_SEL_SOUND_KIT, "SELECT ID, SoundType, Name, VolumeFloat, MinDistance, DistanceCutoff, VolumeVariationPlus, "
+ "VolumeVariationMinus, PitchVariationPlus, PitchVariationMinus, PitchAdjust, Flags, SoundEntriesAdvancedID, EAXDef, DialogType, "
+ "BusOverwriteID, Unk700 FROM sound_kit ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_SOUND_KIT, "SELECT ID, Name_lang FROM sound_kit_locale WHERE locale = ?", CONNECTION_SYNCH);
// SpecializationSpells.db2
- PrepareStatement(HOTFIX_SEL_SPECIALIZATION_SPELLS, "SELECT ID, SpecID, OrderIndex, SpellID, OverridesSpellID, Description"
+ PrepareStatement(HOTFIX_SEL_SPECIALIZATION_SPELLS, "SELECT ID, SpellID, OverridesSpellID, Description, SpecID, OrderIndex"
" FROM specialization_spells ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_SPECIALIZATION_SPELLS, "SELECT ID, Description_lang FROM specialization_spells_locale WHERE locale = ?", CONNECTION_SYNCH);
- // SpellAuraRestrictions.db2
- PrepareStatement(HOTFIX_SEL_SPELL_AURA_RESTRICTIONS, "SELECT ID, CasterAuraState, TargetAuraState, ExcludeCasterAuraState, "
- "ExcludeTargetAuraState, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, ExcludeTargetAuraSpell FROM spell_aura_restrictions"
+ // Spell.db2
+ PrepareStatement(HOTFIX_SEL_SPELL, "SELECT ID, Name, NameSubtext, Description, AuraDescription, MiscID, DescriptionVariablesID FROM spell"
" ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_SPELL, "SELECT ID, Name_lang, NameSubtext_lang, Description_lang, AuraDescription_lang FROM spell_locale"
+ " WHERE locale = ?", CONNECTION_SYNCH);
- // SpellCastingRequirements.db2
- PrepareStatement(HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS, "SELECT ID, FacingCasterFlags, MinFactionID, MinReputation, RequiredAreasID, "
- "RequiredAuraVision, RequiresSpellFocus FROM spell_casting_requirements ORDER BY ID DESC", CONNECTION_SYNCH);
+ // SpellAuraOptions.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_AURA_OPTIONS, "SELECT ID, SpellID, ProcCharges, ProcTypeMask, ProcCategoryRecovery, CumulativeAura, "
+ "DifficultyID, ProcChance, SpellProcsPerMinuteID FROM spell_aura_options ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellAuraRestrictions.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_AURA_RESTRICTIONS, "SELECT ID, SpellID, CasterAuraSpell, TargetAuraSpell, ExcludeCasterAuraSpell, "
+ "ExcludeTargetAuraSpell, DifficultyID, CasterAuraState, TargetAuraState, ExcludeCasterAuraState, ExcludeTargetAuraState"
+ " FROM spell_aura_restrictions ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellCastTimes.db2
- PrepareStatement(HOTFIX_SEL_SPELL_CAST_TIMES, "SELECT ID, CastTime, CastTimePerLevel, MinCastTime FROM spell_cast_times ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_SPELL_CAST_TIMES, "SELECT ID, CastTime, MinCastTime, CastTimePerLevel FROM spell_cast_times ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellCastingRequirements.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS, "SELECT ID, SpellID, MinFactionID, RequiredAreasID, RequiresSpellFocus, "
+ "FacingCasterFlags, MinReputation, RequiredAuraVision FROM spell_casting_requirements ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellCategories.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_CATEGORIES, "SELECT ID, SpellID, Category, StartRecoveryCategory, ChargeCategory, DifficultyID, DefenseType, "
+ "DispelType, Mechanic, PreventionType FROM spell_categories ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellCategory.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_CATEGORY, "SELECT ID, Name, ChargeRecoveryTime, Flags, UsesPerWeek, MaxCharges FROM spell_category"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_SPELL_CATEGORY, "SELECT ID, Name_lang FROM spell_category_locale WHERE locale = ?", CONNECTION_SYNCH);
// SpellClassOptions.db2
- PrepareStatement(HOTFIX_SEL_SPELL_CLASS_OPTIONS, "SELECT ID, ModalNextSpell, SpellClassMask1, SpellClassMask2, SpellClassMask3, SpellClassMask4, "
- "SpellClassSet FROM spell_class_options ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_SPELL_CLASS_OPTIONS, "SELECT ID, SpellID, SpellClassMask1, SpellClassMask2, SpellClassMask3, SpellClassMask4, "
+ "ModalNextSpell, SpellClassSet FROM spell_class_options ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellCooldowns.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_COOLDOWNS, "SELECT ID, SpellID, CategoryRecoveryTime, RecoveryTime, StartRecoveryTime, DifficultyID"
+ " FROM spell_cooldowns ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellDuration.db2
- PrepareStatement(HOTFIX_SEL_SPELL_DURATION, "SELECT ID, Duration1, Duration2, Duration3 FROM spell_duration ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_SPELL_DURATION, "SELECT ID, Duration, MaxDuration, DurationPerLevel FROM spell_duration ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellEffect.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_EFFECT, "SELECT ID, EffectAmplitude, EffectAuraPeriod, EffectBasePoints, EffectBonusCoefficient, "
+ "EffectChainAmplitude, EffectDieSides, EffectItemType, EffectMiscValue, EffectMiscValueB, EffectPointsPerResource, EffectRealPointsPerLevel, "
+ "EffectSpellClassMask1, EffectSpellClassMask2, EffectSpellClassMask3, EffectSpellClassMask4, EffectTriggerSpell, EffectPosFacing, SpellID, "
+ "EffectAttributes, BonusCoefficientFromAP, EffectAura, EffectChainTargets, DifficultyID, Effect, EffectMechanic, EffectRadiusIndex, "
+ "EffectRadiusMaxIndex, ImplicitTarget1, ImplicitTarget2, EffectIndex FROM spell_effect ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellEffectScaling.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_EFFECT_SCALING, "SELECT ID, Coefficient, Variance, ResourceCoefficient, SpellEffectID FROM spell_effect_scaling"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellEquippedItems.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_EQUIPPED_ITEMS, "SELECT ID, SpellID, EquippedItemInventoryTypeMask, EquippedItemSubClassMask, "
+ "EquippedItemClass FROM spell_equipped_items ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellFocusObject.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_FOCUS_OBJECT, "SELECT ID, Name FROM spell_focus_object ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_SPELL_FOCUS_OBJECT, "SELECT ID, Name_lang FROM spell_focus_object_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // SpellInterrupts.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_INTERRUPTS, "SELECT ID, SpellID, AuraInterruptFlags1, AuraInterruptFlags2, ChannelInterruptFlags1, "
+ "ChannelInterruptFlags2, InterruptFlags, DifficultyID FROM spell_interrupts ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellItemEnchantmentCondition.db2
PrepareStatement(HOTFIX_SEL_SPELL_ITEM_ENCHANTMENT_CONDITION, "SELECT ID, LTOperandType1, LTOperandType2, LTOperandType3, LTOperandType4, "
@@ -429,19 +589,22 @@ void HotfixDatabaseConnection::DoPrepareStatements()
// SpellLearnSpell.db2
PrepareStatement(HOTFIX_SEL_SPELL_LEARN_SPELL, "SELECT ID, LearnSpellID, SpellID, OverridesSpellID FROM spell_learn_spell ORDER BY ID DESC", CONNECTION_SYNCH);
+ // SpellLevels.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_LEVELS, "SELECT ID, SpellID, BaseLevel, MaxLevel, SpellLevel, DifficultyID FROM spell_levels ORDER BY ID DESC", CONNECTION_SYNCH);
+
// SpellMisc.db2
PrepareStatement(HOTFIX_SEL_SPELL_MISC, "SELECT ID, Attributes, AttributesEx, AttributesExB, AttributesExC, AttributesExD, AttributesExE, "
- "AttributesExF, AttributesExG, AttributesExH, AttributesExI, AttributesExJ, AttributesExK, AttributesExL, AttributesExM, CastingTimeIndex, "
- "DurationIndex, RangeIndex, Speed, SpellIconID, ActiveIconID, SchoolMask, MultistrikeSpeedMod FROM spell_misc ORDER BY ID DESC", CONNECTION_SYNCH);
+ "AttributesExF, AttributesExG, AttributesExH, AttributesExI, AttributesExJ, AttributesExK, AttributesExL, AttributesExM, Speed, "
+ "MultistrikeSpeedMod, CastingTimeIndex, DurationIndex, RangeIndex, SpellIconID, ActiveIconID, SchoolMask FROM spell_misc ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellPower.db2
- PrepareStatement(HOTFIX_SEL_SPELL_POWER, "SELECT ID, SpellID, PowerIndex, PowerType, ManaCost, ManaCostPerLevel, ManaCostPerSecond, "
- "ManaCostAdditional, PowerDisplayID, UnitPowerBarID, ManaCostPercentage, ManaCostPercentagePerSecond, RequiredAura, HealthCostPercentage"
+ PrepareStatement(HOTFIX_SEL_SPELL_POWER, "SELECT ID, SpellID, ManaCost, ManaCostPercentage, ManaCostPercentagePerSecond, RequiredAura, "
+ "HealthCostPercentage, ManaCostPerSecond, ManaCostAdditional, PowerDisplayID, UnitPowerBarID, PowerIndex, PowerType, ManaCostPerLevel"
" FROM spell_power ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellPowerDifficulty.db2
- PrepareStatement(HOTFIX_SEL_SPELL_POWER_DIFFICULTY, "SELECT SpellPowerID, DifficultyID, PowerIndex FROM spell_power_difficulty"
- " ORDER BY SpellPowerID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_SPELL_POWER_DIFFICULTY, "SELECT ID, SpellPowerID, DifficultyID, PowerIndex FROM spell_power_difficulty"
+ " ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellProcsPerMinute.db2
PrepareStatement(HOTFIX_SEL_SPELL_PROCS_PER_MINUTE, "SELECT ID, BaseProcRate, Flags FROM spell_procs_per_minute ORDER BY ID DESC", CONNECTION_SYNCH);
@@ -454,45 +617,60 @@ void HotfixDatabaseConnection::DoPrepareStatements()
PrepareStatement(HOTFIX_SEL_SPELL_RADIUS, "SELECT ID, Radius, RadiusPerLevel, RadiusMin, RadiusMax FROM spell_radius ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellRange.db2
- PrepareStatement(HOTFIX_SEL_SPELL_RANGE, "SELECT ID, MinRangeHostile, MinRangeFriend, MaxRangeHostile, MaxRangeFriend, Flags, DisplayName, "
- "DisplayNameShort FROM spell_range ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_SPELL_RANGE, "SELECT ID, MinRangeHostile, MinRangeFriend, MaxRangeHostile, MaxRangeFriend, DisplayName, "
+ "DisplayNameShort, Flags FROM spell_range ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_SPELL_RANGE, "SELECT ID, DisplayName_lang, DisplayNameShort_lang FROM spell_range_locale WHERE locale = ?", CONNECTION_SYNCH);
// SpellReagents.db2
- PrepareStatement(HOTFIX_SEL_SPELL_REAGENTS, "SELECT ID, Reagent1, Reagent2, Reagent3, Reagent4, Reagent5, Reagent6, Reagent7, Reagent8, "
+ PrepareStatement(HOTFIX_SEL_SPELL_REAGENTS, "SELECT ID, SpellID, Reagent1, Reagent2, Reagent3, Reagent4, Reagent5, Reagent6, Reagent7, Reagent8, "
"ReagentCount1, ReagentCount2, ReagentCount3, ReagentCount4, ReagentCount5, ReagentCount6, ReagentCount7, ReagentCount8 FROM spell_reagents"
" ORDER BY ID DESC", CONNECTION_SYNCH);
- // SpellRuneCost.db2
- PrepareStatement(HOTFIX_SEL_SPELL_RUNE_COST, "SELECT ID, Blood, Unholy, Frost, Chromatic, RunicPower FROM spell_rune_cost"
+ // SpellScaling.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_SCALING, "SELECT ID, SpellID, ScalesFromItemLevel, ScalingClass, MaxScalingLevel FROM spell_scaling"
" ORDER BY ID DESC", CONNECTION_SYNCH);
+ // SpellShapeshift.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_SHAPESHIFT, "SELECT ID, SpellID, ShapeshiftExclude1, ShapeshiftExclude2, ShapeshiftMask1, ShapeshiftMask2, "
+ "StanceBarOrder FROM spell_shapeshift ORDER BY ID DESC", CONNECTION_SYNCH);
+
+ // SpellShapeshiftForm.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_SHAPESHIFT_FORM, "SELECT ID, Name, WeaponDamageVariance, Flags, AttackIconID, CombatRoundTime, "
+ "CreatureDisplayID1, CreatureDisplayID2, CreatureDisplayID3, CreatureDisplayID4, PresetSpellID1, PresetSpellID2, PresetSpellID3, "
+ "PresetSpellID4, PresetSpellID5, PresetSpellID6, PresetSpellID7, PresetSpellID8, CreatureType, MountTypeID, BonusActionBar"
+ " FROM spell_shapeshift_form ORDER BY ID DESC", CONNECTION_SYNCH);
+ PREPARE_LOCALE_STMT(HOTFIX_SEL_SPELL_SHAPESHIFT_FORM, "SELECT ID, Name_lang FROM spell_shapeshift_form_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // SpellTargetRestrictions.db2
+ PrepareStatement(HOTFIX_SEL_SPELL_TARGET_RESTRICTIONS, "SELECT ID, SpellID, ConeAngle, Width, Targets, MaxTargetLevel, TargetCreatureType, "
+ "DifficultyID, MaxAffectedTargets FROM spell_target_restrictions ORDER BY ID DESC", CONNECTION_SYNCH);
+
// SpellTotems.db2
- PrepareStatement(HOTFIX_SEL_SPELL_TOTEMS, "SELECT ID, RequiredTotemCategoryID1, RequiredTotemCategoryID2, Totem1, Totem2 FROM spell_totems"
- " ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_SPELL_TOTEMS, "SELECT ID, SpellID, Totem1, Totem2, RequiredTotemCategoryID1, RequiredTotemCategoryID2"
+ " FROM spell_totems ORDER BY ID DESC", CONNECTION_SYNCH);
// SpellXSpellVisual.db2
- PrepareStatement(HOTFIX_SEL_SPELL_X_SPELL_VISUAL, "SELECT ID, SpellID, DifficultyID, SpellVisualID1, SpellVisualID2, Unk620, PlayerConditionID, "
+ PrepareStatement(HOTFIX_SEL_SPELL_X_SPELL_VISUAL, "SELECT ID, SpellID, Unk620, SpellVisualID1, SpellVisualID2, PlayerConditionID, DifficultyID, "
"Flags FROM spell_x_spell_visual ORDER BY ID DESC", CONNECTION_SYNCH);
// TaxiNodes.db2
- PrepareStatement(HOTFIX_SEL_TAXI_NODES, "SELECT ID, MapID, PosX, PosY, PosZ, Name, MountCreatureID1, MountCreatureID2, ConditionID, "
- "LearnableIndex, Flags, MapOffsetX, MapOffsetY FROM taxi_nodes ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_TAXI_NODES, "SELECT ID, PosX, PosY, PosZ, Name, MountCreatureID1, MountCreatureID2, MapOffsetX, MapOffsetY, MapID, "
+ "ConditionID, LearnableIndex, Flags FROM taxi_nodes ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_TAXI_NODES, "SELECT ID, Name_lang FROM taxi_nodes_locale WHERE locale = ?", CONNECTION_SYNCH);
// TaxiPath.db2
PrepareStatement(HOTFIX_SEL_TAXI_PATH, "SELECT ID, `From`, `To`, Cost FROM taxi_path ORDER BY ID DESC", CONNECTION_SYNCH);
// TaxiPathNode.db2
- PrepareStatement(HOTFIX_SEL_TAXI_PATH_NODE, "SELECT ID, PathID, NodeIndex, MapID, LocX, LocY, LocZ, Flags, Delay, ArrivalEventID, "
- "DepartureEventID FROM taxi_path_node ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_TAXI_PATH_NODE, "SELECT ID, LocX, LocY, LocZ, Delay, PathID, MapID, ArrivalEventID, DepartureEventID, NodeIndex, "
+ "Flags FROM taxi_path_node ORDER BY ID DESC", CONNECTION_SYNCH);
// TotemCategory.db2
- PrepareStatement(HOTFIX_SEL_TOTEM_CATEGORY, "SELECT ID, Name, CategoryType, CategoryMask FROM totem_category ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_TOTEM_CATEGORY, "SELECT ID, Name, CategoryMask, CategoryType FROM totem_category ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_TOTEM_CATEGORY, "SELECT ID, Name_lang FROM totem_category_locale WHERE locale = ?", CONNECTION_SYNCH);
// Toy.db2
- PrepareStatement(HOTFIX_SEL_TOY, "SELECT ID, ItemID, Flags, Description, CategoryFilter FROM toy ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_TOY, "SELECT ID, ItemID, Description, Flags, CategoryFilter FROM toy ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_TOY, "SELECT ID, Description_lang FROM toy_locale WHERE locale = ?", CONNECTION_SYNCH);
// TransportAnimation.db2
@@ -503,15 +681,18 @@ void HotfixDatabaseConnection::DoPrepareStatements()
PrepareStatement(HOTFIX_SEL_TRANSPORT_ROTATION, "SELECT ID, TransportID, TimeIndex, X, Y, Z, W FROM transport_rotation ORDER BY ID DESC", CONNECTION_SYNCH);
// UnitPowerBar.db2
- PrepareStatement(HOTFIX_SEL_UNIT_POWER_BAR, "SELECT ID, MinPower, MaxPower, StartPower, CenterPower, RegenerationPeace, RegenerationCombat, "
- "BarType, FileDataID1, FileDataID2, FileDataID3, FileDataID4, FileDataID5, FileDataID6, Color1, Color2, Color3, Color4, Color5, Color6, "
- "Flags, Name, Cost, OutOfError, ToolTip, StartInset, EndInset FROM unit_power_bar ORDER BY ID DESC", CONNECTION_SYNCH);
+ PrepareStatement(HOTFIX_SEL_UNIT_POWER_BAR, "SELECT ID, MaxPower, RegenerationPeace, RegenerationCombat, FileDataID1, FileDataID2, FileDataID3, "
+ "FileDataID4, FileDataID5, FileDataID6, Color1, Color2, Color3, Color4, Color5, Color6, Name, Cost, OutOfError, ToolTip, StartInset, "
+ "EndInset, StartPower, Flags, MinPower, CenterPower, BarType FROM unit_power_bar ORDER BY ID DESC", CONNECTION_SYNCH);
PREPARE_LOCALE_STMT(HOTFIX_SEL_UNIT_POWER_BAR, "SELECT ID, Name_lang, Cost_lang, OutOfError_lang, ToolTip_lang FROM unit_power_bar_locale"
" WHERE locale = ?", CONNECTION_SYNCH);
// WorldMapOverlay.db2
- PrepareStatement(HOTFIX_SEL_WORLD_MAP_OVERLAY, "SELECT ID, MapAreaID, AreaID1, AreaID2, AreaID3, AreaID4, TextureName, TextureWidth, "
+ PrepareStatement(HOTFIX_SEL_WORLD_MAP_OVERLAY, "SELECT ID, TextureName, MapAreaID, AreaID1, AreaID2, AreaID3, AreaID4, TextureWidth, "
"TextureHeight, OffsetX, OffsetY, HitRectTop, HitRectLeft, HitRectBottom, HitRectRight, PlayerConditionID FROM world_map_overlay"
" ORDER BY ID DESC", CONNECTION_SYNCH);
- PREPARE_LOCALE_STMT(HOTFIX_SEL_WORLD_MAP_OVERLAY, "SELECT ID, TextureName_lang FROM world_map_overlay_locale WHERE locale = ?", CONNECTION_SYNCH);
+
+ // WorldMapTransforms.db2
+ PrepareStatement(HOTFIX_SEL_WORLD_MAP_TRANSFORMS, "SELECT ID, RegionMinX, RegionMinY, RegionMinZ, RegionMaxX, RegionMaxY, RegionMaxZ, "
+ "RegionOffsetX, RegionOffsetY, RegionScale, MapID, NewMapID, NewDungeonMapID, NewAreaID, Flags FROM world_map_transforms ORDER BY ID DESC", CONNECTION_SYNCH);
}
diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h
index 999c9316dad..322df76d74d 100644
--- a/src/server/database/Database/Implementation/HotfixDatabase.h
+++ b/src/server/database/Database/Implementation/HotfixDatabase.h
@@ -35,11 +35,17 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_ACHIEVEMENT,
HOTFIX_SEL_ACHIEVEMENT_LOCALE,
+ HOTFIX_SEL_ANIM_KIT,
+
HOTFIX_SEL_AREA_GROUP_MEMBER,
+ HOTFIX_SEL_ARMOR_LOCATION,
+
HOTFIX_SEL_AUCTION_HOUSE,
HOTFIX_SEL_AUCTION_HOUSE_LOCALE,
+ HOTFIX_SEL_BANK_BAG_SLOT_PRICES,
+
HOTFIX_SEL_BARBER_SHOP_STYLE,
HOTFIX_SEL_BARBER_SHOP_STYLE_LOCALE,
@@ -59,10 +65,14 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_CHR_CLASSES_X_POWER_TYPES,
+ HOTFIX_SEL_CHR_RACES,
+ HOTFIX_SEL_CHR_RACES_LOCALE,
+
HOTFIX_SEL_CINEMATIC_SEQUENCES,
HOTFIX_SEL_CREATURE_DISPLAY_INFO,
- HOTFIX_SEL_CREATURE_DISPLAY_INFO_LOCALE,
+
+ HOTFIX_SEL_CREATURE_DISPLAY_INFO_EXTRA,
HOTFIX_SEL_CREATURE_TYPE,
HOTFIX_SEL_CREATURE_TYPE_LOCALE,
@@ -79,11 +89,17 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_DESTRUCTIBLE_MODEL_DATA,
+ HOTFIX_SEL_DURABILITY_COSTS,
+
HOTFIX_SEL_DURABILITY_QUALITY,
+ HOTFIX_SEL_EMOTES_TEXT_SOUND,
+
HOTFIX_SEL_GAMEOBJECTS,
HOTFIX_SEL_GAMEOBJECTS_LOCALE,
+ HOTFIX_SEL_GAMEOBJECT_DISPLAY_INFO,
+
HOTFIX_SEL_GAME_TABLES,
HOTFIX_SEL_GAME_TABLES_LOCALE,
@@ -117,13 +133,18 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_GLYPH_SLOT,
+ HOTFIX_SEL_GUILD_COLOR_BACKGROUND,
+
+ HOTFIX_SEL_GUILD_COLOR_BORDER,
+
+ HOTFIX_SEL_GUILD_COLOR_EMBLEM,
+
HOTFIX_SEL_GUILD_PERK_SPELLS,
HOTFIX_SEL_HEIRLOOM,
HOTFIX_SEL_HEIRLOOM_LOCALE,
HOTFIX_SEL_HOLIDAYS,
- HOTFIX_SEL_HOLIDAYS_LOCALE,
HOTFIX_SEL_IMPORT_PRICE_ARMOR,
@@ -133,8 +154,19 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_IMPORT_PRICE_WEAPON,
+ HOTFIX_SEL_ITEM,
+
HOTFIX_SEL_ITEM_APPEARANCE,
+ HOTFIX_SEL_ITEM_ARMOR_QUALITY,
+
+ HOTFIX_SEL_ITEM_ARMOR_SHIELD,
+
+ HOTFIX_SEL_ITEM_ARMOR_TOTAL,
+
+ HOTFIX_SEL_ITEM_BAG_FAMILY,
+ HOTFIX_SEL_ITEM_BAG_FAMILY_LOCALE,
+
HOTFIX_SEL_ITEM_BONUS,
HOTFIX_SEL_ITEM_BONUS_TREE_NODE,
@@ -144,12 +176,20 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_ITEM_CURRENCY_COST,
+ HOTFIX_SEL_ITEM_DAMAGE_AMMO,
+
+ HOTFIX_SEL_ITEM_DAMAGE_ONE_HAND,
+
+ HOTFIX_SEL_ITEM_DAMAGE_ONE_HAND_CASTER,
+
+ HOTFIX_SEL_ITEM_DAMAGE_TWO_HAND,
+
+ HOTFIX_SEL_ITEM_DAMAGE_TWO_HAND_CASTER,
+
HOTFIX_SEL_ITEM_DISENCHANT_LOOT,
HOTFIX_SEL_ITEM_EFFECT,
- HOTFIX_SEL_ITEM,
-
HOTFIX_SEL_ITEM_EXTENDED_COST,
HOTFIX_SEL_ITEM_LIMIT_CATEGORY,
@@ -165,6 +205,8 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_ITEM_RANDOM_SUFFIX,
HOTFIX_SEL_ITEM_RANDOM_SUFFIX_LOCALE,
+ HOTFIX_SEL_ITEM_SET_SPELL,
+
HOTFIX_SEL_ITEM_SPARSE,
HOTFIX_SEL_ITEM_SPARSE_LOCALE,
@@ -190,6 +232,8 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_MOUNT_TYPE_X_CAPABILITY,
+ HOTFIX_SEL_MOVIE,
+
HOTFIX_SEL_NAME_GEN,
HOTFIX_SEL_NAME_GEN_LOCALE,
@@ -206,6 +250,10 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_PLAYER_CONDITION,
HOTFIX_SEL_PLAYER_CONDITION_LOCALE,
+ HOTFIX_SEL_POWER_DISPLAY,
+
+ HOTFIX_SEL_QUEST_FACTION_REWARD,
+
HOTFIX_SEL_QUEST_MONEY_REWARD,
HOTFIX_SEL_QUEST_PACKAGE_ITEM,
@@ -217,28 +265,62 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_QUEST_XP,
+ HOTFIX_SEL_RAND_PROP_POINTS,
+
HOTFIX_SEL_SCALING_STAT_DISTRIBUTION,
- HOTFIX_SEL_SOUND_ENTRIES,
- HOTFIX_SEL_SOUND_ENTRIES_LOCALE,
+ HOTFIX_SEL_SKILL_LINE,
+ HOTFIX_SEL_SKILL_LINE_LOCALE,
+
+ HOTFIX_SEL_SKILL_LINE_ABILITY,
+
+ HOTFIX_SEL_SKILL_RACE_CLASS_INFO,
+
+ HOTFIX_SEL_SOUND_KIT,
+ HOTFIX_SEL_SOUND_KIT_LOCALE,
HOTFIX_SEL_SPECIALIZATION_SPELLS,
HOTFIX_SEL_SPECIALIZATION_SPELLS_LOCALE,
+ HOTFIX_SEL_SPELL,
+ HOTFIX_SEL_SPELL_LOCALE,
+
+ HOTFIX_SEL_SPELL_AURA_OPTIONS,
+
HOTFIX_SEL_SPELL_AURA_RESTRICTIONS,
+ HOTFIX_SEL_SPELL_CAST_TIMES,
+
HOTFIX_SEL_SPELL_CASTING_REQUIREMENTS,
- HOTFIX_SEL_SPELL_CAST_TIMES,
+ HOTFIX_SEL_SPELL_CATEGORIES,
+
+ HOTFIX_SEL_SPELL_CATEGORY,
+ HOTFIX_SEL_SPELL_CATEGORY_LOCALE,
HOTFIX_SEL_SPELL_CLASS_OPTIONS,
+ HOTFIX_SEL_SPELL_COOLDOWNS,
+
HOTFIX_SEL_SPELL_DURATION,
+ HOTFIX_SEL_SPELL_EFFECT,
+
+ HOTFIX_SEL_SPELL_EFFECT_SCALING,
+
+ HOTFIX_SEL_SPELL_EQUIPPED_ITEMS,
+
+ HOTFIX_SEL_SPELL_FOCUS_OBJECT,
+ HOTFIX_SEL_SPELL_FOCUS_OBJECT_LOCALE,
+
+ HOTFIX_SEL_SPELL_INTERRUPTS,
+
HOTFIX_SEL_SPELL_ITEM_ENCHANTMENT_CONDITION,
HOTFIX_SEL_SPELL_LEARN_SPELL,
+ HOTFIX_SEL_SPELL_LEVELS,
+
HOTFIX_SEL_SPELL_MISC,
HOTFIX_SEL_SPELL_POWER,
@@ -256,7 +338,14 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_SPELL_REAGENTS,
- HOTFIX_SEL_SPELL_RUNE_COST,
+ HOTFIX_SEL_SPELL_SCALING,
+
+ HOTFIX_SEL_SPELL_SHAPESHIFT,
+
+ HOTFIX_SEL_SPELL_SHAPESHIFT_FORM,
+ HOTFIX_SEL_SPELL_SHAPESHIFT_FORM_LOCALE,
+
+ HOTFIX_SEL_SPELL_TARGET_RESTRICTIONS,
HOTFIX_SEL_SPELL_TOTEMS,
@@ -283,7 +372,8 @@ enum HotfixDatabaseStatements
HOTFIX_SEL_UNIT_POWER_BAR_LOCALE,
HOTFIX_SEL_WORLD_MAP_OVERLAY,
- HOTFIX_SEL_WORLD_MAP_OVERLAY_LOCALE,
+
+ HOTFIX_SEL_WORLD_MAP_TRANSFORMS,
MAX_HOTFIXDATABASE_STATEMENTS
};
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;
diff --git a/src/server/scripts/Commands/cs_debug.cpp b/src/server/scripts/Commands/cs_debug.cpp
index b2094df08ef..59eb97d1476 100644
--- a/src/server/scripts/Commands/cs_debug.cpp
+++ b/src/server/scripts/Commands/cs_debug.cpp
@@ -171,7 +171,7 @@ public:
uint32 soundId = atoi((char*)args);
- if (!sSoundEntriesStore.LookupEntry(soundId))
+ if (!sSoundKitStore.LookupEntry(soundId))
{
handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId);
handler->SetSentErrorMessage(true);
diff --git a/src/server/scripts/Commands/cs_learn.cpp b/src/server/scripts/Commands/cs_learn.cpp
index 16e94242021..5f31d7f806f 100644
--- a/src/server/scripts/Commands/cs_learn.cpp
+++ b/src/server/scripts/Commands/cs_learn.cpp
@@ -325,7 +325,7 @@ public:
if ((skillInfo->CategoryID == SKILL_CATEGORY_PROFESSION || skillInfo->CategoryID == SKILL_CATEGORY_SECONDARY) &&
skillInfo->CanLink) // only prof. with recipes have
{
- HandleLearnSkillRecipesHelper(target, skillInfo->ID);
+ HandleLearnSkillRecipesHelper(target, i);
}
}
@@ -358,7 +358,7 @@ public:
std::string name;
- SkillLineEntry const* targetSkillInfo = NULL;
+ uint32 skillId = 0;
for (uint32 i = 1; i < sSkillLineStore.GetNumRows(); ++i)
{
SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(i);
@@ -370,23 +370,42 @@ public:
!skillInfo->CanLink) // only prof with recipes have set
continue;
- name = skillInfo->DisplayName_lang;
+ int locale = handler->GetSessionDbcLocale();
+ name = skillInfo->DisplayName->Str[locale];
if (name.empty())
continue;
if (!Utf8FitTo(name, namePart))
- continue;
+ {
+ locale = 0;
+ for (; locale < TOTAL_LOCALES; ++locale)
+ {
+ if (locale == handler->GetSessionDbcLocale())
+ continue;
- targetSkillInfo = skillInfo;
+ name = skillInfo->DisplayName->Str[locale];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, namePart))
+ break;
+ }
+ }
+
+ if (locale < TOTAL_LOCALES)
+ {
+ skillId = i;
+ break;
+ }
}
- if (!targetSkillInfo)
+ if (!skillId)
return false;
- HandleLearnSkillRecipesHelper(target, targetSkillInfo->ID);
+ HandleLearnSkillRecipesHelper(target, skillId);
- uint16 maxLevel = target->GetPureMaxSkillValue(targetSkillInfo->ID);
- target->SetSkill(targetSkillInfo->ID, target->GetSkillStep(targetSkillInfo->ID), maxLevel, maxLevel);
+ uint16 maxLevel = target->GetPureMaxSkillValue(skillId);
+ target->SetSkill(skillId, target->GetSkillStep(skillId), maxLevel, maxLevel);
handler->PSendSysMessage(LANG_COMMAND_LEARN_ALL_RECIPES, name.c_str());
return true;
}
diff --git a/src/server/scripts/Commands/cs_list.cpp b/src/server/scripts/Commands/cs_list.cpp
index 67c89a2f10c..b66fc95c407 100644
--- a/src/server/scripts/Commands/cs_list.cpp
+++ b/src/server/scripts/Commands/cs_list.cpp
@@ -436,7 +436,7 @@ public:
AuraApplication const* aurApp = itr->second;
Aura const* aura = aurApp->GetBase();
- char const* name = aura->GetSpellInfo()->SpellName;
+ char const* name = aura->GetSpellInfo()->SpellName->Str[handler->GetSessionDbcLocale()];
bool talent = aura->GetSpellInfo()->HasAttribute(SPELL_ATTR0_CU_IS_TALENT);
std::ostringstream ss_name;
diff --git a/src/server/scripts/Commands/cs_lookup.cpp b/src/server/scripts/Commands/cs_lookup.cpp
index 57bf557771b..b032aa8ef2e 100644
--- a/src/server/scripts/Commands/cs_lookup.cpp
+++ b/src/server/scripts/Commands/cs_lookup.cpp
@@ -688,41 +688,59 @@ public:
SkillLineEntry const* skillInfo = sSkillLineStore.LookupEntry(id);
if (skillInfo)
{
- std::string name = skillInfo->DisplayName_lang;
+ int locale = handler->GetSessionDbcLocale();
+ std::string name = skillInfo->DisplayName->Str[locale];
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- continue;
-
- if (maxResults && count++ == maxResults)
{
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
+ locale = 0;
+ for (; locale < TOTAL_LOCALES; ++locale)
+ {
+ if (locale == handler->GetSessionDbcLocale())
+ continue;
+
+ name = skillInfo->DisplayName->Str[locale];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wNamePart))
+ break;
+ }
}
- char valStr[50] = "";
- char const* knownStr = "";
- if (target && target->HasSkill(id))
+ if (locale < TOTAL_LOCALES)
{
- knownStr = handler->GetTrinityString(LANG_KNOWN);
- uint32 curValue = target->GetPureSkillValue(id);
- uint32 maxValue = target->GetPureMaxSkillValue(id);
- uint32 permValue = target->GetSkillPermBonusValue(id);
- uint32 tempValue = target->GetSkillTempBonusValue(id);
-
- char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES);
- snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue);
- }
+ if (maxResults && count++ == maxResults)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- // send skill in "id - [namedlink locale]" format
- if (handler->GetSession())
- handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), "", knownStr, valStr);
- else
- handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), "", knownStr, valStr);
+ char valStr[50] = "";
+ char const* knownStr = "";
+ if (target && target->HasSkill(id))
+ {
+ knownStr = handler->GetTrinityString(LANG_KNOWN);
+ uint32 curValue = target->GetPureSkillValue(id);
+ uint32 maxValue = target->GetPureMaxSkillValue(id);
+ uint32 permValue = target->GetSkillPermBonusValue(id);
+ uint32 tempValue = target->GetSkillTempBonusValue(id);
+
+ char const* valFormat = handler->GetTrinityString(LANG_SKILL_VALUES);
+ snprintf(valStr, 50, valFormat, curValue, maxValue, permValue, tempValue);
+ }
- if (!found)
- found = true;
+ // send skill in "id - [namedlink locale]" format
+ if (handler->GetSession())
+ handler->PSendSysMessage(LANG_SKILL_LIST_CHAT, id, id, name.c_str(), "", knownStr, valStr);
+ else
+ handler->PSendSysMessage(LANG_SKILL_LIST_CONSOLE, id, name.c_str(), "", knownStr, valStr);
+
+ if (!found)
+ found = true;
+ }
}
}
if (!found)
@@ -758,63 +776,81 @@ public:
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id);
if (spellInfo)
{
- std::string name = spellInfo->SpellName;
+ int locale = handler->GetSessionDbcLocale();
+ std::string name = spellInfo->SpellName->Str[locale];
if (name.empty())
continue;
if (!Utf8FitTo(name, wNamePart))
- continue;
-
- if (maxResults && count++ == maxResults)
{
- handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
- return true;
+ locale = 0;
+ for (; locale < TOTAL_LOCALES; ++locale)
+ {
+ if (locale == handler->GetSessionDbcLocale())
+ continue;
+
+ name = spellInfo->SpellName->Str[locale];
+ if (name.empty())
+ continue;
+
+ if (Utf8FitTo(name, wNamePart))
+ break;
+ }
}
- bool known = target && target->HasSpell(id);
+ if (locale < TOTAL_LOCALES)
+ {
+ if (maxResults && count++ == maxResults)
+ {
+ handler->PSendSysMessage(LANG_COMMAND_LOOKUP_MAX_RESULTS, maxResults);
+ return true;
+ }
- SpellEffectInfo const* effect = spellInfo->GetEffect(EFFECT_0);
- bool learn = effect ? (effect->Effect == SPELL_EFFECT_LEARN_SPELL) : false;
+ bool known = target && target->HasSpell(id);
- SpellInfo const* learnSpellInfo = effect ? sSpellMgr->GetSpellInfo(effect->TriggerSpell) : NULL;
+ SpellEffectInfo const* effect = spellInfo->GetEffect(EFFECT_0);
+ bool learn = effect ? (effect->Effect == SPELL_EFFECT_LEARN_SPELL) : false;
- bool talent = spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT);
- bool passive = spellInfo->IsPassive();
- bool active = target && target->HasAura(id);
+ SpellInfo const* learnSpellInfo = effect ? sSpellMgr->GetSpellInfo(effect->TriggerSpell) : NULL;
- // unit32 used to prevent interpreting uint8 as char at output
- // find rank of learned spell for learning spell, or talent rank
- uint32 rank = learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
+ bool talent = spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT);
+ bool passive = spellInfo->IsPassive();
+ bool active = target && target->HasAura(id);
- // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
- std::ostringstream ss;
- if (handler->GetSession())
- ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
- else
- ss << id << " - " << name;
+ // unit32 used to prevent interpreting uint8 as char at output
+ // find rank of learned spell for learning spell, or talent rank
+ uint32 rank = learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
- // include rank in link name
- if (rank)
- ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank;
+ // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
+ std::ostringstream ss;
+ if (handler->GetSession())
+ ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
+ else
+ ss << id << " - " << name;
- if (handler->GetSession())
- ss << "]|h|r";
-
- if (talent)
- ss << handler->GetTrinityString(LANG_TALENT);
- if (passive)
- ss << handler->GetTrinityString(LANG_PASSIVE);
- if (learn)
- ss << handler->GetTrinityString(LANG_LEARN);
- if (known)
- ss << handler->GetTrinityString(LANG_KNOWN);
- if (active)
- ss << handler->GetTrinityString(LANG_ACTIVE);
+ // include rank in link name
+ if (rank)
+ ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank;
- handler->SendSysMessage(ss.str().c_str());
+ if (handler->GetSession())
+ ss << "]|h|r";
+
+ if (talent)
+ ss << handler->GetTrinityString(LANG_TALENT);
+ if (passive)
+ ss << handler->GetTrinityString(LANG_PASSIVE);
+ if (learn)
+ ss << handler->GetTrinityString(LANG_LEARN);
+ if (known)
+ ss << handler->GetTrinityString(LANG_KNOWN);
+ if (active)
+ ss << handler->GetTrinityString(LANG_ACTIVE);
- if (!found)
- found = true;
+ handler->SendSysMessage(ss.str().c_str());
+
+ if (!found)
+ found = true;
+ }
}
}
if (!found)
@@ -836,56 +872,56 @@ public:
if (SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(id))
{
int locale = handler->GetSessionDbcLocale();
- std::string name = spellInfo->SpellName;
+ std::string name = spellInfo->SpellName->Str[locale];
if (name.empty())
{
handler->SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
return true;
}
- bool known = target && target->HasSpell(id);
+ bool known = target && target->HasSpell(id);
- SpellEffectInfo const* effect = spellInfo->GetEffect(EFFECT_0);
- bool learn = effect? (effect->Effect == SPELL_EFFECT_LEARN_SPELL) : false;
+ SpellEffectInfo const* effect = spellInfo->GetEffect(EFFECT_0);
+ bool learn = effect? (effect->Effect == SPELL_EFFECT_LEARN_SPELL) : false;
- SpellInfo const* learnSpellInfo = effect ? sSpellMgr->GetSpellInfo(effect->TriggerSpell) : NULL;
+ SpellInfo const* learnSpellInfo = effect ? sSpellMgr->GetSpellInfo(effect->TriggerSpell) : NULL;
- bool talent = spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT);
- bool passive = spellInfo->IsPassive();
- bool active = target && target->HasAura(id);
+ bool talent = spellInfo->HasAttribute(SPELL_ATTR0_CU_IS_TALENT);
+ bool passive = spellInfo->IsPassive();
+ bool active = target && target->HasAura(id);
- // unit32 used to prevent interpreting uint8 as char at output
- // find rank of learned spell for learning spell, or talent rank
- uint32 rank = learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
+ // unit32 used to prevent interpreting uint8 as char at output
+ // find rank of learned spell for learning spell, or talent rank
+ uint32 rank = learn && learnSpellInfo ? learnSpellInfo->GetRank() : spellInfo->GetRank();
- // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
- std::ostringstream ss;
- if (handler->GetSession())
- ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
- else
- ss << id << " - " << name;
-
- // include rank in link name
- if (rank)
- ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank;
+ // send spell in "id - [name, rank N] [talent] [passive] [learn] [known]" format
+ std::ostringstream ss;
+ if (handler->GetSession())
+ ss << id << " - |cffffffff|Hspell:" << id << "|h[" << name;
+ else
+ ss << id << " - " << name;
- if (handler->GetSession())
- ss << ' ' << localeNames[locale] << "]|h|r";
- else
- ss << ' ' << localeNames[locale];
-
- if (talent)
- ss << handler->GetTrinityString(LANG_TALENT);
- if (passive)
- ss << handler->GetTrinityString(LANG_PASSIVE);
- if (learn)
- ss << handler->GetTrinityString(LANG_LEARN);
- if (known)
- ss << handler->GetTrinityString(LANG_KNOWN);
- if (active)
- ss << handler->GetTrinityString(LANG_ACTIVE);
+ // include rank in link name
+ if (rank)
+ ss << handler->GetTrinityString(LANG_SPELL_RANK) << rank;
- handler->SendSysMessage(ss.str().c_str());
+ if (handler->GetSession())
+ ss << ' ' << localeNames[locale] << "]|h|r";
+ else
+ ss << ' ' << localeNames[locale];
+
+ if (talent)
+ ss << handler->GetTrinityString(LANG_TALENT);
+ if (passive)
+ ss << handler->GetTrinityString(LANG_PASSIVE);
+ if (learn)
+ ss << handler->GetTrinityString(LANG_LEARN);
+ if (known)
+ ss << handler->GetTrinityString(LANG_KNOWN);
+ if (active)
+ ss << handler->GetTrinityString(LANG_ACTIVE);
+
+ handler->SendSysMessage(ss.str().c_str());
}
else
handler->SendSysMessage(LANG_COMMAND_NOSPELLFOUND);
diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp
index 7ad80352995..e6fb42853e3 100644
--- a/src/server/scripts/Commands/cs_misc.cpp
+++ b/src/server/scripts/Commands/cs_misc.cpp
@@ -755,7 +755,7 @@ public:
}
target->GetSpellHistory()->ResetCooldown(spellIid, true);
- target->GetSpellHistory()->ResetCharges(spellInfo->ChargeCategoryEntry);
+ target->GetSpellHistory()->ResetCharges(spellInfo->ChargeCategoryId);
handler->PSendSysMessage(LANG_REMOVE_COOLDOWN, spellIid, target == handler->GetSession()->GetPlayer() ? handler->GetTrinityString(LANG_YOU) : nameLink.c_str());
}
return true;
@@ -1168,10 +1168,10 @@ public:
if (itemNameStr && itemNameStr[0])
{
std::string itemName = itemNameStr+1;
- auto itr = std::find_if(sItemSparseStore.begin(), sItemSparseStore.end(), [&itemName](ItemSparseEntry const* itemSparse)
+ auto itr = std::find_if(sItemSparseStore.begin(), sItemSparseStore.end(), [&itemName](std::pair<uint32, ItemSparseEntry const*> kv)
{
for (uint32 i = 0; i < MAX_LOCALES; ++i)
- if (itemName == itemSparse->Name->Str[i])
+ if (itemName == kv.second->Name->Str[i])
return true;
return false;
});
@@ -1183,7 +1183,7 @@ public:
return false;
}
- itemId = itr->ID;
+ itemId = itr->first;
}
else
return false;
@@ -1469,7 +1469,7 @@ public:
// add the skill to the player's book with step 1 (which is the first rank, in most cases something
// like 'Apprentice <skill>'.
target->SetSkill(skill, targetHasSkill ? target->GetSkillStep(skill) : 1, level, max);
- handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->DisplayName_lang, handler->GetNameLink(target).c_str(), level, max);
+ handler->PSendSysMessage(LANG_SET_SKILL, skill, skillLine->DisplayName->Str[handler->GetSessionDbcLocale()], handler->GetNameLink(target).c_str(), level, max);
return true;
}
@@ -1573,7 +1573,7 @@ public:
uint8 raceid, classid = 0; //RACE_NONE, CLASS_NONE
std::string raceStr, classStr = handler->GetTrinityString(LANG_UNKNOWN);
uint8 gender = 0;
- int8 locale = handler->GetSessionDbcLocale();
+ LocaleConstant locale = handler->GetSessionDbcLocale();
uint32 totalPlayerTime = 0;
uint8 level = 0;
std::string alive = handler->GetTrinityString(LANG_ERROR);
@@ -1794,7 +1794,7 @@ public:
handler->PSendSysMessage(LANG_PINFO_CHR_LEVEL_HIGH, level);
// Output XI. LANG_PINFO_CHR_RACE
- raceStr = GetRaceName(raceid, locale);
+ raceStr = DB2Manager::GetChrRaceName(raceid, locale);
classStr = GetClassName(classid, locale);
handler->PSendSysMessage(LANG_PINFO_CHR_RACE, (gender == 0 ? handler->GetTrinityString(LANG_CHARACTER_GENDER_MALE) : handler->GetTrinityString(LANG_CHARACTER_GENDER_FEMALE)), raceStr.c_str(), classStr.c_str());
@@ -2608,7 +2608,7 @@ public:
uint32 soundId = atoi((char*)args);
- if (!sSoundEntriesStore.LookupEntry(soundId))
+ if (!sSoundKitStore.LookupEntry(soundId))
{
handler->PSendSysMessage(LANG_SOUND_NOT_EXIST, soundId);
handler->SetSentErrorMessage(true);
@@ -2688,7 +2688,7 @@ public:
{
AuraApplication const* aurApp = itr->second;
Aura const* aura = aurApp->GetBase();
- char const* name = aura->GetSpellInfo()->SpellName;
+ char const* name = aura->GetSpellInfo()->SpellName->Str[handler->GetSessionDbcLocale()];
bool self = target->GetGUID() == aura->GetCasterGUID();
if (self)
diff --git a/src/server/scripts/Spells/spell_druid.cpp b/src/server/scripts/Spells/spell_druid.cpp
index 4488561589f..a4665973009 100644
--- a/src/server/scripts/Spells/spell_druid.cpp
+++ b/src/server/scripts/Spells/spell_druid.cpp
@@ -172,7 +172,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
int32 energizeAmount = -GetEffectValue(); // -13
// If we are set to fill the lunar side or we've just logged in with 0 power..
if ((!caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER))
- || caster->GetPower(POWER_ECLIPSE) == 0)
+ || caster->GetPower(POWER_LUNAR_POWER) == 0)
{
caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true);
// If the energize was due to 0 power, cast the eclipse marker aura
@@ -180,7 +180,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
caster->CastSpell(caster, SPELL_DRUID_LUNAR_ECLIPSE_MARKER, true);
}
// The energizing effect brought us out of the solar eclipse, remove the aura
- if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0)
+ if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_LUNAR_POWER) <= 0)
caster->RemoveAurasDueToSpell(SPELL_DRUID_SOLAR_ECLIPSE);
break;
}
@@ -189,7 +189,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
int32 energizeAmount = GetEffectValue(); // 20
// If we are set to fill the solar side or we've just logged in with 0 power..
if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER))
- || caster->GetPower(POWER_ECLIPSE) == 0)
+ || caster->GetPower(POWER_LUNAR_POWER) == 0)
{
caster->CastCustomSpell(caster, SPELL_DRUID_ECLIPSE_GENERAL_ENERGIZE, &energizeAmount, 0, 0, true);
// If the energize was due to 0 power, cast the eclipse marker aura
@@ -197,7 +197,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
caster->CastSpell(caster, SPELL_DRUID_SOLAR_ECLIPSE_MARKER, true);
}
// The energizing effect brought us out of the lunar eclipse, remove the aura
- if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0)
+ if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_LUNAR_POWER) >= 0)
caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE);
break;
}
@@ -205,7 +205,7 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
{
// If we are set to fill the solar side or we've just logged in with 0 power (confirmed with sniffs)
if ((!caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE_MARKER) && caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE_MARKER))
- || caster->GetPower(POWER_ECLIPSE) == 0)
+ || caster->GetPower(POWER_LUNAR_POWER) == 0)
{
int32 energizeAmount = GetEffectValue(); // 15
caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true);
@@ -220,10 +220,10 @@ class spell_dru_eclipse_energize : public SpellScriptLoader
caster->CastCustomSpell(caster, SPELL_DRUID_STARSURGE_ENERGIZE, &energizeAmount, 0, 0, true);
}
// The energizing effect brought us out of the lunar eclipse, remove the aura
- if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) >= 0)
+ if (caster->HasAura(SPELL_DRUID_LUNAR_ECLIPSE) && caster->GetPower(POWER_LUNAR_POWER) >= 0)
caster->RemoveAura(SPELL_DRUID_LUNAR_ECLIPSE);
// The energizing effect brought us out of the solar eclipse, remove the aura
- else if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_ECLIPSE) <= 0)
+ else if (caster->HasAura(SPELL_DRUID_SOLAR_ECLIPSE) && caster->GetPower(POWER_LUNAR_POWER) <= 0)
caster->RemoveAura(SPELL_DRUID_SOLAR_ECLIPSE);
break;
}
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index b0853c71b2c..7dcd3a4fbb9 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -2706,7 +2706,7 @@ public:
if (Player* target = GetHitUnit()->ToPlayer())
{
target->HandleEmoteCommand(EMOTE_ONESHOT_TRAIN);
- if (EmotesTextSoundEntry const* soundEntry = FindTextSoundEmoteFor(TEXT_EMOTE_TRAIN, target->getRace(), target->getGender()))
+ if (EmotesTextSoundEntry const* soundEntry = sDB2Manager.GetTextSoundEmoteFor(TEXT_EMOTE_TRAIN, target->getRace(), target->getGender(), target->getClass()))
target->PlayDistanceSound(soundEntry->SoundId);
}
}
diff --git a/src/server/shared/DataStores/DB2SparseStorageLoader.cpp b/src/server/shared/DataStores/DB2SparseStorageLoader.cpp
new file mode 100644
index 00000000000..2e7e974cb5d
--- /dev/null
+++ b/src/server/shared/DataStores/DB2SparseStorageLoader.cpp
@@ -0,0 +1,683 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "Common.h"
+#include "DB2SparseStorageLoader.h"
+#include "Database/DatabaseEnv.h"
+#include "Log.h"
+
+DB2SparseFileLoader::DB2SparseFileLoader()
+{
+ fileName = nullptr;
+
+ recordCount = 0;
+ fieldCount = 0;
+ recordSize = 0;
+ offsetsPos = 0;
+ tableHash = 0;
+ build = 0;
+ unk1 = 0;
+ minIndex = 0;
+ maxIndex = 0;
+ localeMask = 0;
+ copyIdSize = 0;
+
+ dataStart = 0;
+ data = nullptr;
+ offsets = nullptr;
+}
+
+bool DB2SparseFileLoader::Load(const char *filename)
+{
+ if (data)
+ {
+ delete[] data;
+ data = nullptr;
+ }
+
+ FILE* f = fopen(filename, "rb");
+ if (!f)
+ return false;
+
+ fileName = filename;
+ uint32 header;
+ if (fread(&header, 4, 1, f) != 1) // Signature
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(header);
+
+ if (header != 0x34424457)
+ {
+ fclose(f);
+ return false; //'WDB4'
+ }
+
+ if (fread(&recordCount, 4, 1, f) != 1) // Number of records
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(recordCount);
+
+ if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(fieldCount);
+
+ if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(recordSize);
+
+ if (fread(&offsetsPos, 4, 1, f) != 1) // String size
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(offsetsPos);
+
+ if (fread(&tableHash, 4, 1, f) != 1) // Table hash
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(tableHash);
+
+ if (fread(&build, 4, 1, f) != 1) // Build
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(build);
+
+ if (fread(&unk1, 4, 1, f) != 1) // Unknown WDB2
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(unk1);
+
+ if (fread(&minIndex, 4, 1, f) != 1) // MinIndex WDB2
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(minIndex);
+
+ if (fread(&maxIndex, 4, 1, f) != 1) // MaxIndex WDB2
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(maxIndex);
+
+ if (fread(&localeMask, 4, 1, f) != 1) // Locales
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(localeMask);
+
+ if (fread(&copyIdSize, 4, 1, f) != 1)
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(copyIdSize);
+
+ if (fread(&metaFlags, 4, 1, f) != 1)
+ {
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(metaFlags);
+
+ dataStart = ftell(f);
+
+ data = new unsigned char[offsetsPos - dataStart];
+
+ if (fread(data, offsetsPos - dataStart, 1, f) != 1)
+ {
+ fclose(f);
+ return false;
+ }
+
+ offsets = new OffsetTableEntry[maxIndex - minIndex + 1];
+ if (fread(offsets, (maxIndex - minIndex + 1) * 6, 1, f) != 1)
+ {
+ fclose(f);
+ return false;
+ }
+
+ fclose(f);
+ return true;
+}
+
+DB2SparseFileLoader::~DB2SparseFileLoader()
+{
+ delete[] data;
+ delete[] offsets;
+}
+
+uint32 DB2SparseFileLoader::GetFormatRecordSize(const char * format)
+{
+ uint32 recordsize = 0;
+ for (uint32 x = 0; format[x]; ++x)
+ {
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ case FT_INT:
+ recordsize += 4;
+ break;
+ case FT_STRING:
+ case FT_STRING_NOT_LOCALIZED:
+ recordsize += sizeof(char*);
+ break;
+ case FT_BYTE:
+ recordsize += 1;
+ break;
+ case FT_LONG:
+ recordsize += 8;
+ break;
+ case FT_SHORT:
+ recordsize += 2;
+ break;
+ }
+ }
+
+ return recordsize;
+}
+
+uint32 DB2SparseFileLoader::GetFormatStringFieldCount(const char* format)
+{
+ uint32 stringfields = 0;
+ for (uint32 x = 0; format[x]; ++x)
+ if (format[x] == FT_STRING || format[x] == FT_STRING_NOT_LOCALIZED)
+ ++stringfields;
+
+ return stringfields;
+}
+
+uint32 DB2SparseFileLoader::GetFormatLocalizedStringFieldCount(char const* format)
+{
+ uint32 stringfields = 0;
+ for (uint32 x = 0; format[x]; ++x)
+ if (format[x] == FT_STRING)
+ ++stringfields;
+
+ return stringfields;
+}
+
+static char const* const nullStr = "";
+
+char* DB2SparseFileLoader::AutoProduceData(const char* format, IndexTable const& indexTable, uint32 locale, std::vector<char*>& stringPool)
+{
+ typedef char* ptr;
+ if (strlen(format) != fieldCount)
+ return NULL;
+
+ //get struct size and index pos
+ uint32 recordsize = GetFormatRecordSize(format);
+
+ uint32 offsetCount = maxIndex - minIndex + 1;
+ uint32 records = 0;
+ uint32 expandedDataSize = 0;
+ for (uint32 i = 0; i < offsetCount; ++i)
+ {
+ if (offsets[i].FileOffset && offsets[i].RecordSize)
+ {
+ ++records;
+ expandedDataSize += offsets[i].RecordSize;
+ }
+ }
+
+ char* dataTable = new char[records * recordsize];
+
+ // we store flat holders pool as single memory block
+ std::size_t stringFields = GetFormatStringFieldCount(format);
+ std::size_t localizedStringFields = GetFormatLocalizedStringFieldCount(format);
+
+ // each string field at load have array of string for each locale
+ std::size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
+ std::size_t stringHoldersRecordPoolSize = localizedStringFields * stringHolderSize + (stringFields - localizedStringFields) * sizeof(char*);
+ std::size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * records;
+
+ char* stringHoldersPool = new char[stringHoldersPoolSize];
+ stringPool.push_back(stringHoldersPool);
+
+ // DB2 strings expected to have at least empty string
+ for (std::size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i)
+ ((char const**)stringHoldersPool)[i] = nullStr;
+
+ char* stringTable = new char[expandedDataSize - records * (recordsize - stringFields * sizeof(char*))];
+ memset(stringTable, 0, expandedDataSize - records * (recordsize - stringFields * sizeof(char*)));
+ stringPool.push_back(stringTable);
+ char* stringPtr = stringTable;
+
+ uint32 offset = 0;
+ uint32 recordNum = 0;
+ for (uint32 y = 0; y < offsetCount; ++y)
+ {
+ if (!offsets[y].FileOffset || !offsets[y].RecordSize)
+ continue;
+
+ indexTable.Insert(y + minIndex, &dataTable[offset]);
+ uint32 fieldOffset = 0;
+ uint32 stringFieldOffset = 0;
+ for (uint32 x = 0; x < fieldCount; x++)
+ {
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ *((float*)(&dataTable[offset])) = *reinterpret_cast<float*>(&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ offset += 4;
+ fieldOffset += 4;
+ break;
+ case FT_IND:
+ case FT_INT:
+ *((uint32*)(&dataTable[offset])) = *reinterpret_cast<uint32*>(&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ offset += 4;
+ fieldOffset += 4;
+ break;
+ case FT_BYTE:
+ *((uint8*)(&dataTable[offset])) = *reinterpret_cast<uint8*>(&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ offset += 1;
+ fieldOffset += 1;
+ break;
+ case FT_LONG:
+ *((uint64*)(&dataTable[offset])) = *reinterpret_cast<uint64*>(&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ offset += 8;
+ fieldOffset += 8;
+ break;
+ case FT_SHORT:
+ *((uint16*)(&dataTable[offset])) = *reinterpret_cast<uint16*>(&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ offset += 2;
+ fieldOffset += 2;
+ break;
+ case FT_STRING:
+ {
+ LocalizedString** slot = (LocalizedString**)(&dataTable[offset]);
+ *slot = (LocalizedString*)(&stringHoldersPool[stringHoldersRecordPoolSize * recordNum + stringFieldOffset]);
+ (*slot)->Str[locale] = stringPtr;
+ strcpy(stringPtr, (char*)&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ fieldOffset += strlen(stringPtr) + 1;
+ stringPtr += strlen(stringPtr) + 1;
+ stringFieldOffset += stringHolderSize;
+ offset += sizeof(LocalizedString*);
+ break;
+ }
+ case FT_STRING_NOT_LOCALIZED:
+ {
+ char const*** slot = (char const***)(&dataTable[offset]);
+ *slot = (char const**)(&stringHoldersPool[stringHoldersRecordPoolSize * recordNum + stringFieldOffset]);
+ **slot = stringPtr;
+ strcpy(stringPtr, (char*)&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ fieldOffset += strlen(stringPtr) + 1;
+ stringPtr += strlen(stringPtr) + 1;
+ ++stringFieldOffset;
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+
+ ++recordNum;
+ }
+
+ return dataTable;
+}
+
+char* DB2SparseFileLoader::AutoProduceStrings(const char* format, char* dataTable, uint32 locale)
+{
+ if (strlen(format) != fieldCount)
+ return nullptr;
+
+ if (!(localeMask & (1 << locale)))
+ {
+ char const* sep = "";
+ std::ostringstream str;
+ for (uint32 i = 0; i < TOTAL_LOCALES; ++i)
+ {
+ if (localeMask & (1 << i))
+ {
+ str << sep << localeNames[i];
+ sep = ", ";
+ }
+ }
+
+ TC_LOG_ERROR("", "Attempted to load %s which has locales %s as %s. Check if you placed your localized db2 files in correct directory.", fileName, str.str().c_str(), localeNames[locale]);
+ return nullptr;
+ }
+
+ uint32 offsetCount = maxIndex - minIndex + 1;
+ uint32 records = 0;
+ for (uint32 i = 0; i < offsetCount; ++i)
+ if (offsets[i].FileOffset && offsets[i].RecordSize)
+ ++records;
+
+ uint32 recordsize = GetFormatRecordSize(format);
+ std::size_t stringFields = GetFormatStringFieldCount(format);
+ char* stringTable = new char[offsetsPos - dataStart - records * (recordsize - stringFields * sizeof(char*))];
+ memset(stringTable, 0, offsetsPos - dataStart - records * (recordsize - stringFields * sizeof(char*)));
+ char* stringPtr = stringTable;
+
+ uint32 offset = 0;
+
+ for (uint32 y = 0; y < offsetCount; y++)
+ {
+ if (!offsets[y].FileOffset || !offsets[y].RecordSize)
+ continue;
+
+ uint32 fieldOffset;
+ for (uint32 x = 0; x < fieldCount; x++)
+ {
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ case FT_IND:
+ case FT_INT:
+ offset += 4;
+ fieldOffset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ fieldOffset += 1;
+ break;
+ case FT_LONG:
+ offset += 8;
+ fieldOffset += 8;
+ break;
+ case FT_SHORT:
+ offset += 2;
+ fieldOffset += 2;
+ break;
+ case FT_STRING:
+ {
+ // fill only not filled entries
+ LocalizedString* db2str = *(LocalizedString**)(&dataTable[offset]);
+ db2str->Str[locale] = stringPtr;
+ strcpy(stringPtr, (char*)&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ fieldOffset += strlen(stringPtr) + 1;
+ stringPtr += strlen(stringPtr) + 1;
+ offset += sizeof(char*);
+ break;
+ }
+ case FT_STRING_NOT_LOCALIZED:
+ {
+ char** db2str = (char**)(&dataTable[offset]);
+ *db2str = stringPtr;
+ strcpy(stringPtr, (char*)&data[offsets[y].FileOffset - dataStart + fieldOffset]);
+ fieldOffset += strlen(stringPtr) + 1;
+ stringPtr += strlen(stringPtr) + 1;
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+ }
+
+ return stringTable;
+}
+
+char* DB2SparseDatabaseLoader::Load(const char* format, HotfixDatabaseStatements preparedStatement, IndexTable const& indexTable, std::vector<char*>& stringPool)
+{
+ // Even though this query is executed only once, prepared statement is used to send data from mysql server in binary format
+ PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement));
+ if (!result)
+ return nullptr;
+
+ uint32 const fieldCount = strlen(format);
+ if (fieldCount != result->GetFieldCount())
+ return nullptr;
+
+ // get struct size and index pos
+ uint32 recordSize = DB2SparseFileLoader::GetFormatRecordSize(format);
+
+ // we store flat holders pool as single memory block
+ std::size_t stringFields = DB2SparseFileLoader::GetFormatStringFieldCount(format);
+ std::size_t localizedStringFields = DB2SparseFileLoader::GetFormatLocalizedStringFieldCount(format);
+
+ // each string field at load have array of string for each locale
+ std::size_t stringHolderSize = sizeof(char*) * TOTAL_LOCALES;
+ std::size_t stringHoldersRecordPoolSize = localizedStringFields * stringHolderSize + (stringFields - localizedStringFields) * sizeof(char*);
+
+ char* stringHolders = nullptr;
+ if (stringFields)
+ {
+ std::size_t stringHoldersPoolSize = stringHoldersRecordPoolSize * result->GetRowCount();
+ stringHolders = new char[stringHoldersPoolSize];
+ stringPool.push_back(stringHolders);
+
+ // DB2 strings expected to have at least empty string
+ for (std::size_t i = 0; i < stringHoldersPoolSize / sizeof(char*); ++i)
+ ((char const**)stringHolders)[i] = nullStr;
+ }
+
+ char* tempDataTable = new char[result->GetRowCount() * recordSize];
+ uint32* newIndexes = new uint32[result->GetRowCount()];
+ uint32 rec = 0;
+ uint32 newRecords = 0;
+
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 offset = 0;
+ uint32 stringFieldOffset = 0;
+
+ uint32 indexValue = fields[0].GetUInt32();
+
+ // Attempt to overwrite existing data
+ char* dataValue = indexTable.Get(indexValue);
+ if (!dataValue)
+ {
+ newIndexes[newRecords] = indexValue;
+ dataValue = &tempDataTable[newRecords++ * recordSize];
+ }
+
+ for (uint32 f = 0; f < fieldCount; f++)
+ {
+ switch (format[f])
+ {
+ case FT_FLOAT:
+ *((float*)(&dataValue[offset])) = fields[f].GetFloat();
+ offset += 4;
+ break;
+ case FT_IND:
+ case FT_INT:
+ *((int32*)(&dataValue[offset])) = fields[f].GetInt32();
+ offset += 4;
+ break;
+ case FT_BYTE:
+ *((int8*)(&dataValue[offset])) = fields[f].GetInt8();
+ offset += 1;
+ break;
+ case FT_LONG:
+ *((int64*)(&dataValue[offset])) = fields[f].GetInt64();
+ offset += 8;
+ break;
+ case FT_SHORT:
+ *((int16*)(&dataValue[offset])) = fields[f].GetInt16();
+ offset += 2;
+ break;
+ case FT_STRING:
+ {
+ LocalizedString** slot = (LocalizedString**)(&dataValue[offset]);
+ *slot = (LocalizedString*)(&stringHolders[stringHoldersRecordPoolSize * rec + stringFieldOffset]);
+ ASSERT(*slot);
+
+ // Value in database in main table field must be for enUS locale
+ if (char* str = AddString(&(*slot)->Str[LOCALE_enUS], fields[f].GetString()))
+ stringPool.push_back(str);
+
+ stringFieldOffset += stringHolderSize;
+ offset += sizeof(char*);
+ break;
+ }
+ case FT_STRING_NOT_LOCALIZED:
+ {
+ char const** slot = (char const**)(&dataValue[offset]);
+ *slot = (char*)(&stringHolders[stringHoldersRecordPoolSize * rec + stringFieldOffset]);
+ ASSERT(*slot);
+
+ // Value in database in main table field must be for enUS locale
+ if (char* str = AddString(slot, fields[f].GetString()))
+ stringPool.push_back(str);
+
+ ++stringFieldOffset;
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+
+ ASSERT(offset == recordSize);
+ ++rec;
+ } while (result->NextRow());
+
+ if (!newRecords)
+ {
+ delete[] tempDataTable;
+ delete[] newIndexes;
+ return nullptr;
+ }
+
+ // Compact new data table to only contain new records not previously loaded from file
+ char* dataTable = new char[newRecords * recordSize];
+ memcpy(dataTable, tempDataTable, newRecords * recordSize);
+
+ // insert new records to index table
+ for (uint32 i = 0; i < newRecords; ++i)
+ indexTable.Insert(newIndexes[i], &dataTable[i * recordSize]);
+
+ delete[] tempDataTable;
+ delete[] newIndexes;
+
+ return dataTable;
+}
+
+void DB2SparseDatabaseLoader::LoadStrings(const char* format, HotfixDatabaseStatements preparedStatement, uint32 locale, IndexTable const& indexTable, std::vector<char*>& stringPool)
+{
+ PreparedStatement* stmt = HotfixDatabase.GetPreparedStatement(preparedStatement);
+ stmt->setString(0, localeNames[locale]);
+ PreparedQueryResult result = HotfixDatabase.Query(stmt);
+ if (!result)
+ return;
+
+ size_t stringFields = DB2SparseFileLoader::GetFormatLocalizedStringFieldCount(format);
+ if (result->GetFieldCount() != stringFields + 1 /*ID*/)
+ return;
+
+ uint32 const fieldCount = strlen(format);
+ uint32 recordSize = DB2SparseFileLoader::GetFormatRecordSize(format);
+ ASSERT(0 >= 0, "DB2Storage must be indexed to load localized strings");
+
+ do
+ {
+ Field* fields = result->Fetch();
+ uint32 offset = 0;
+ uint32 stringFieldNumInRecord = 0;
+ uint32 indexValue = fields[0].GetUInt32();
+
+ // Attempt to overwrite existing data
+ if (char* dataValue = indexTable.Get(indexValue))
+ {
+ for (uint32 x = 0; x < fieldCount; x++)
+ {
+ switch (format[x])
+ {
+ case FT_FLOAT:
+ case FT_IND:
+ case FT_INT:
+ offset += 4;
+ break;
+ case FT_BYTE:
+ offset += 1;
+ break;
+ case FT_LONG:
+ offset += 8;
+ break;
+ case FT_SHORT:
+ offset += 2;
+ break;
+ case FT_STRING:
+ {
+ // fill only not filled entries
+ LocalizedString* db2str = *(LocalizedString**)(&dataValue[offset]);
+ if (db2str->Str[locale] == nullStr)
+ if (char* str = AddString(&db2str->Str[locale], fields[1 + stringFieldNumInRecord].GetString()))
+ stringPool.push_back(str);
+
+ ++stringFieldNumInRecord;
+ offset += sizeof(char*);
+ break;
+ }
+ }
+ }
+
+ ASSERT(offset == recordSize);
+ }
+ else
+ TC_LOG_ERROR("sql.sql", "Hotfix locale table for storage %s references row that does not exist %u!", _storageName.c_str(), indexValue);
+
+ } while (result->NextRow());
+
+ return;
+}
+
+char* DB2SparseDatabaseLoader::AddString(char const** holder, std::string const& value)
+{
+ if (!value.empty())
+ {
+ std::size_t existingLength = strlen(*holder);
+ if (existingLength >= value.length())
+ {
+ // Reuse existing storage if there is enough space
+ char* str = const_cast<char*>(*holder);
+ memcpy(str, value.c_str(), value.length());
+ str[value.length()] = '\0';
+ return nullptr;
+ }
+
+ char* str = new char[value.length() + 1];
+ memcpy(str, value.c_str(), value.length());
+ str[value.length()] = '\0';
+ *holder = str;
+ return str;
+ }
+
+ return nullptr;
+}
diff --git a/src/server/shared/DataStores/DB2SparseStorageLoader.h b/src/server/shared/DataStores/DB2SparseStorageLoader.h
new file mode 100644
index 00000000000..13f31e12d56
--- /dev/null
+++ b/src/server/shared/DataStores/DB2SparseStorageLoader.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef DB2_SPARSE_FILE_LOADER_H
+#define DB2_SPARSE_FILE_LOADER_H
+
+#include "Define.h"
+#include "Utilities/ByteConverter.h"
+#include "Implementation/HotfixDatabase.h"
+#include <unordered_map>
+#include <vector>
+
+class IndexTable
+{
+public:
+ virtual void Insert(uint32 index, char* data) const = 0;
+ virtual char* Get(uint32 index) const = 0;
+};
+
+template<typename T>
+class IndexTableAdapter : public IndexTable
+{
+public:
+ IndexTableAdapter(std::unordered_map<uint32, T const*>& indexTable) : _indexTable(indexTable) { }
+
+ void Insert(uint32 index, char* data) const override
+ {
+ _indexTable[index] = (T const*)data;
+ }
+
+ char* Get(uint32 index) const override
+ {
+ auto itr = _indexTable.find(index);
+ if (itr != _indexTable.end())
+ return (char*)itr->second;
+ return nullptr;
+ }
+
+private:
+ std::unordered_map<uint32, T const*>& _indexTable;
+};
+
+class DB2SparseFileLoader
+{
+ public:
+ DB2SparseFileLoader();
+ ~DB2SparseFileLoader();
+
+ bool Load(const char *filename);
+
+ uint32 GetNumRows() const { return recordCount; }
+ uint32 GetCols() const { return fieldCount; }
+ uint32 GetHash() const { return tableHash; }
+ bool IsLoaded() const { return (data != NULL); }
+ char* AutoProduceData(const char* fmt, IndexTable const& indexTable, uint32 locale, std::vector<char*>& stringPool);
+ char* AutoProduceStrings(const char* fmt, char* dataTable, uint32 locale);
+ static uint32 GetFormatRecordSize(const char * format);
+ static uint32 GetFormatStringFieldCount(const char * format);
+ static uint32 GetFormatLocalizedStringFieldCount(const char * format);
+private:
+#pragma pack(push, 1)
+ struct OffsetTableEntry
+ {
+ uint32 FileOffset;
+ uint16 RecordSize;
+ };
+#pragma pack(pop)
+
+ char const* fileName;
+
+ // WDB2 / WCH2 fields
+ uint32 recordSize;
+ uint32 recordCount;
+ uint32 fieldCount;
+ uint32 offsetsPos;
+ uint32 tableHash;
+ uint32 build;
+ uint32 unk1;
+ uint32 minIndex;
+ uint32 maxIndex;
+ uint32 localeMask;
+ uint32 copyIdSize;
+ uint32 metaFlags;
+
+ uint32 dataStart;
+ unsigned char* data;
+ OffsetTableEntry* offsets;
+};
+
+class DB2SparseDatabaseLoader
+{
+public:
+ explicit DB2SparseDatabaseLoader(std::string const& storageName) : _storageName(storageName) { }
+
+ char* Load(const char* format, HotfixDatabaseStatements preparedStatement, IndexTable const& indexTable, std::vector<char*>& stringPool);
+ void LoadStrings(const char* format, HotfixDatabaseStatements preparedStatement, uint32 locale, IndexTable const& indexTable, std::vector<char*>& stringPool);
+ static char* AddString(char const** holder, std::string const& value);
+
+private:
+ std::string _storageName;
+};
+
+#endif
diff --git a/src/server/shared/DataStores/DB2StorageLoader.cpp b/src/server/shared/DataStores/DB2StorageLoader.cpp
index d2be433806f..d101d12a52e 100644
--- a/src/server/shared/DataStores/DB2StorageLoader.cpp
+++ b/src/server/shared/DataStores/DB2StorageLoader.cpp
@@ -23,22 +23,25 @@
DB2FileLoader::DB2FileLoader()
{
fileName = nullptr;
+
recordSize = 0;
recordCount = 0;
fieldCount = 0;
stringSize = 0;
- fieldsOffset = nullptr;
- data = nullptr;
- stringTable = nullptr;
-
tableHash = 0;
build = 0;
-
unk1 = 0;
minIndex = 0;
maxIndex = 0;
localeMask = 0;
- unk5 = 0;
+ copyIdSize = 0;
+
+ fieldsOffset = nullptr;
+ data = nullptr;
+ stringTable = nullptr;
+ idTable = nullptr;
+ idTableSize = 0;
+ copyTable = nullptr;
}
bool DB2FileLoader::Load(const char *filename, const char *fmt)
@@ -55,7 +58,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
fileName = filename;
uint32 header;
- if (fread(&header, 4, 1, f) != 1) // Signature
+ if (fread(&header, 4, 1, f) != 1) // Signature
{
fclose(f);
return false;
@@ -63,13 +66,13 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(header);
- if (header != 0x32424457)
+ if (header != 0x34424457)
{
fclose(f);
- return false; //'WDB2'
+ return false; //'WDB4'
}
- if (fread(&recordCount, 4, 1, f) != 1) // Number of records
+ if (fread(&recordCount, 4, 1, f) != 1) // Number of records
{
fclose(f);
return false;
@@ -77,7 +80,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(recordCount);
- if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
+ if (fread(&fieldCount, 4, 1, f) != 1) // Number of fields
{
fclose(f);
return false;
@@ -85,7 +88,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(fieldCount);
- if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
+ if (fread(&recordSize, 4, 1, f) != 1) // Size of a record
{
fclose(f);
return false;
@@ -93,7 +96,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(recordSize);
- if (fread(&stringSize, 4, 1, f) != 1) // String size
+ if (fread(&stringSize, 4, 1, f) != 1) // String size
{
fclose(f);
return false;
@@ -101,8 +104,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(stringSize);
- /* NEW WDB2 FIELDS*/
- if (fread(&tableHash, 4, 1, f) != 1) // Table hash
+ if (fread(&tableHash, 4, 1, f) != 1) // Table hash
{
fclose(f);
return false;
@@ -110,7 +112,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(tableHash);
- if (fread(&build, 4, 1, f) != 1) // Build
+ if (fread(&build, 4, 1, f) != 1) // Build
{
fclose(f);
return false;
@@ -118,7 +120,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(build);
- if (fread(&unk1, 4, 1, f) != 1) // Unknown WDB2
+ if (fread(&unk1, 4, 1, f) != 1) // Unknown WDB2
{
fclose(f);
return false;
@@ -126,7 +128,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(unk1);
- if (fread(&minIndex, 4, 1, f) != 1) // MinIndex WDB2
+ if (fread(&minIndex, 4, 1, f) != 1) // MinIndex WDB2
{
fclose(f);
return false;
@@ -134,7 +136,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(minIndex);
- if (fread(&maxIndex, 4, 1, f) != 1) // MaxIndex WDB2
+ if (fread(&maxIndex, 4, 1, f) != 1) // MaxIndex WDB2
{
fclose(f);
return false;
@@ -142,7 +144,7 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(maxIndex);
- if (fread(&localeMask, 4, 1, f) != 1) // Locales
+ if (fread(&localeMask, 4, 1, f) != 1) // Locales
{
fclose(f);
return false;
@@ -150,18 +152,26 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
EndianConvert(localeMask);
- if (fread(&unk5, 4, 1, f) != 1) // Unknown WDB2
+ if (fread(&copyIdSize, 4, 1, f) != 1)
{
fclose(f);
return false;
}
- EndianConvert(unk5);
+ EndianConvert(copyIdSize);
- if (maxIndex != 0)
+ if (fread(&metaFlags, 4, 1, f) != 1)
{
- int32 diff = maxIndex - minIndex + 1;
- fseek(f, diff * 4 + diff * 2, SEEK_CUR); // diff * 4: an index for rows, diff * 2: a memory allocation bank
+ fclose(f);
+ return false;
+ }
+
+ EndianConvert(metaFlags);
+
+ if (fmt[0] == FT_SORT)
+ {
+ idTableSize = recordCount * sizeof(uint32);
+ ++fmt;
}
fieldsOffset = new uint32[fieldCount];
@@ -173,6 +183,8 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
fieldsOffset[i] += 1;
else if (fmt[i - 1] == FT_LONG)
fieldsOffset[i] += 8;
+ else if (fmt[i - 1] == FT_SHORT)
+ fieldsOffset[i] += 2;
else // 4 byte fields (int32/float/strings)
fieldsOffset[i] += 4;
}
@@ -186,29 +198,49 @@ bool DB2FileLoader::Load(const char *filename, const char *fmt)
return false;
}
+ if (idTableSize)
+ {
+ idTable = new unsigned char[idTableSize];
+ if (fread(idTable, idTableSize, 1, f) != 1)
+ {
+ fclose(f);
+ return false;
+ }
+ }
+
+ if (copyIdSize)
+ {
+ copyTable = new unsigned char[copyIdSize];
+ if (fread(copyTable, copyIdSize, 1, f) != 1)
+ {
+ fclose(f);
+ return false;
+ }
+ }
+
fclose(f);
return true;
}
DB2FileLoader::~DB2FileLoader()
{
- if (data)
- delete [] data;
- if (fieldsOffset)
- delete [] fieldsOffset;
+ delete[] data;
+ delete[] idTable;
+ delete[] copyTable;
+ delete[] fieldsOffset;
}
DB2FileLoader::Record DB2FileLoader::getRecord(size_t id)
{
assert(data);
- return Record(*this, data + id*recordSize);
+ return Record(*this, data + id * recordSize);
}
uint32 DB2FileLoader::GetFormatRecordSize(const char * format, int32* index_pos)
{
uint32 recordsize = 0;
int32 i = -1;
- for (uint32 x=0; format[x]; ++x)
+ for (uint32 x = 0; format[x]; ++x)
{
switch (format[x])
{
@@ -233,6 +265,9 @@ uint32 DB2FileLoader::GetFormatRecordSize(const char * format, int32* index_pos)
case FT_LONG:
recordsize += 8;
break;
+ case FT_SHORT:
+ recordsize += 2;
+ break;
}
}
@@ -264,8 +299,8 @@ uint32 DB2FileLoader::GetFormatLocalizedStringFieldCount(char const* format)
char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable)
{
- typedef char * ptr;
- if (strlen(format) != fieldCount)
+ typedef char* ptr;
+ if (strlen(format) != fieldCount + (format[0] == FT_SORT ? 1 : 0))
return NULL;
//get struct size and index pos
@@ -276,9 +311,28 @@ char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**
{
uint32 maxi = 0;
//find max index
- for (uint32 y = 0; y < recordCount; y++)
+ if (!idTableSize)
+ {
+ for (uint32 y = 0; y < recordCount; ++y)
+ {
+ uint32 ind = getRecord(y).getUInt(indexField);
+ if (ind > maxi)
+ maxi = ind;
+ }
+ }
+ else
{
- uint32 ind = getRecord(y).getUInt(indexField);
+ ASSERT(indexField == 0);
+ for (uint32 y = 0; y < recordCount; ++y)
+ {
+ uint32 ind = ((uint32*)idTable)[y];
+ if (ind > maxi)
+ maxi = ind;
+ }
+ }
+ for (uint32 y = 0; y < copyIdSize; y += 8)
+ {
+ uint32 ind = *((uint32*)(copyTable + y));
if (ind > maxi)
maxi = ind;
}
@@ -290,18 +344,25 @@ char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**
}
else
{
+ ASSERT(!copyIdSize, "Storage %s uses id copy table - must be indexed!", fileName);
records = recordCount;
indexTable = new ptr[recordCount];
}
- char* dataTable = new char[recordCount * recordsize];
+ char* dataTable = new char[(recordCount + (copyIdSize / 8)) * recordsize];
uint32 offset = 0;
+ if (idTableSize)
+ {
+ ASSERT(format[0] == 'd');
+ ++format;
+ }
+
for (uint32 y = 0; y < recordCount; y++)
{
if (indexField >= 0)
- indexTable[getRecord(y).getUInt(indexField)] = &dataTable[offset];
+ indexTable[!idTableSize ? getRecord(y).getUInt(indexField) : ((uint32*)idTable)[y]] = &dataTable[offset];
else
indexTable[y] = &dataTable[offset];
@@ -326,6 +387,10 @@ char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**
*((uint64*)(&dataTable[offset])) = getRecord(y).getUInt64(x);
offset += 8;
break;
+ case FT_SHORT:
+ *((uint16*)(&dataTable[offset])) = getRecord(y).getUInt16(x);
+ offset += 2;
+ break;
case FT_STRING:
case FT_STRING_NOT_LOCALIZED:
*((char**)(&dataTable[offset])) = nullptr; // will be replaces non-empty or "" strings in AutoProduceStrings
@@ -335,6 +400,20 @@ char* DB2FileLoader::AutoProduceData(const char* format, uint32& records, char**
}
}
+ uint32* copyIds = (uint32*)copyTable;
+ for (uint32 c = 0; c < copyIdSize / 4; c += 2)
+ {
+ uint32 to = copyIds[c];
+ uint32 from = copyIds[c + 1];
+
+ if (from && from < records && indexTable[from])
+ {
+ indexTable[to] = &dataTable[offset];
+ memcpy(indexTable[to], indexTable[from], recordsize);
+ offset += recordsize;
+ }
+ }
+
return dataTable;
}
@@ -342,7 +421,7 @@ static char const* const nullStr = "";
char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* dataTable)
{
- if (strlen(format) != fieldCount)
+ if (strlen(format) != fieldCount + (format[0] == FT_SORT ? 1 : 0))
return nullptr;
// we store flat holders pool as single memory block
@@ -365,6 +444,9 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da
uint32 offset = 0;
+ if (idTableSize)
+ ++format;
+
// assign string holders to string field slots
for (uint32 y = 0; y < recordCount; y++)
{
@@ -385,6 +467,9 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da
case FT_LONG:
offset += 8;
break;
+ case FT_SHORT:
+ offset += 2;
+ break;
case FT_STRING:
case FT_STRING_NOT_LOCALIZED:
{
@@ -411,7 +496,7 @@ char* DB2FileLoader::AutoProduceStringsArrayHolders(const char* format, char* da
char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uint32 locale)
{
- if (strlen(format) != fieldCount)
+ if (strlen(format) != fieldCount + (format[0] == FT_SORT ? 1 : 0))
return nullptr;
if (!(localeMask & (1 << locale)))
@@ -436,6 +521,9 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uin
uint32 offset = 0;
+ if (idTableSize)
+ ++format;
+
for (uint32 y = 0; y < recordCount; y++)
{
for (uint32 x = 0; x < fieldCount; x++)
@@ -453,6 +541,9 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uin
case FT_LONG:
offset += 8;
break;
+ case FT_SHORT:
+ offset += 2;
+ break;
case FT_STRING:
{
// fill only not filled entries
@@ -481,7 +572,7 @@ char* DB2FileLoader::AutoProduceStrings(const char* format, char* dataTable, uin
return stringPool;
}
-char* DB2DatabaseLoader::Load(const char* format, HotfixDatabaseStatements preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool)
+char* DB2DatabaseLoader::Load(const char* format, HotfixDatabaseStatements preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::vector<char*>& stringPool)
{
// Even though this query is executed only once, prepared statement is used to send data from mysql server in binary format
PreparedQueryResult result = HotfixDatabase.Query(HotfixDatabase.GetPreparedStatement(preparedStatement));
@@ -582,6 +673,10 @@ char* DB2DatabaseLoader::Load(const char* format, HotfixDatabaseStatements prepa
*((int64*)(&dataValue[offset])) = fields[f].GetInt64();
offset += 8;
break;
+ case FT_SHORT:
+ *((int16*)(&dataValue[offset])) = fields[f].GetInt16();
+ offset += 2;
+ break;
case FT_STRING:
{
LocalizedString** slot = (LocalizedString**)(&dataValue[offset]);
@@ -640,7 +735,7 @@ char* DB2DatabaseLoader::Load(const char* format, HotfixDatabaseStatements prepa
return dataTable;
}
-void DB2DatabaseLoader::LoadStrings(const char* format, HotfixDatabaseStatements preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool)
+void DB2DatabaseLoader::LoadStrings(const char* format, HotfixDatabaseStatements preparedStatement, uint32 locale, char**& indexTable, std::vector<char*>& stringPool)
{
PreparedStatement* stmt = HotfixDatabase.GetPreparedStatement(preparedStatement);
stmt->setString(0, localeNames[locale]);
@@ -682,6 +777,9 @@ void DB2DatabaseLoader::LoadStrings(const char* format, HotfixDatabaseStatements
case FT_LONG:
offset += 8;
break;
+ case FT_SHORT:
+ offset += 2;
+ break;
case FT_STRING:
{
// fill only not filled entries
diff --git a/src/server/shared/DataStores/DB2StorageLoader.h b/src/server/shared/DataStores/DB2StorageLoader.h
index 41705c67f19..67525779ef5 100644
--- a/src/server/shared/DataStores/DB2StorageLoader.h
+++ b/src/server/shared/DataStores/DB2StorageLoader.h
@@ -22,7 +22,7 @@
#include "Utilities/ByteConverter.h"
#include "Implementation/HotfixDatabase.h"
#include <cassert>
-#include <list>
+#include <vector>
class TC_SHARED_API DB2FileLoader
{
@@ -61,6 +61,13 @@ class TC_SHARED_API DB2FileLoader
EndianConvert(val);
return val;
}
+ uint16 getUInt16(size_t field) const
+ {
+ assert(field < file.fieldCount);
+ uint16 val = *reinterpret_cast<uint16*>(offset + file.GetOffset(field));
+ EndianConvert(val);
+ return val;
+ }
const char *getString(size_t field) const
{
assert(field < file.fieldCount);
@@ -95,23 +102,26 @@ class TC_SHARED_API DB2FileLoader
private:
char const* fileName;
+ // WDB2 / WCH2 fields
uint32 recordSize;
uint32 recordCount;
uint32 fieldCount;
uint32 stringSize;
- uint32 *fieldsOffset;
- unsigned char *data;
- unsigned char *stringTable;
+ uint32 tableHash;
+ uint32 build;
+ uint32 unk1;
+ uint32 minIndex;
+ uint32 maxIndex;
+ uint32 localeMask;
+ uint32 copyIdSize;
+ uint32 metaFlags;
- // WDB2 / WCH2 fields
- uint32 tableHash; // WDB2
- uint32 build; // WDB2
-
- int unk1; // WDB2 (Unix time in WCH2)
- int minIndex; // WDB2
- int maxIndex; // WDB2 (index table)
- int localeMask; // WDB2
- int unk5; // WDB2
+ uint32 *fieldsOffset;
+ unsigned char* data;
+ unsigned char* stringTable;
+ unsigned char* idTable;
+ uint32 idTableSize;
+ unsigned char* copyTable;
};
class TC_SHARED_API DB2DatabaseLoader
@@ -119,8 +129,8 @@ class TC_SHARED_API DB2DatabaseLoader
public:
explicit DB2DatabaseLoader(std::string const& storageName) : _storageName(storageName) { }
- char* Load(const char* format, HotfixDatabaseStatements preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::list<char*>& stringPool);
- void LoadStrings(const char* format, HotfixDatabaseStatements preparedStatement, uint32 locale, char**& indexTable, std::list<char*>& stringPool);
+ char* Load(const char* format, HotfixDatabaseStatements preparedStatement, uint32& records, char**& indexTable, char*& stringHolders, std::vector<char*>& stringPool);
+ void LoadStrings(const char* format, HotfixDatabaseStatements preparedStatement, uint32 locale, char**& indexTable, std::vector<char*>& stringPool);
static char* AddString(char const** holder, std::string const& value);
private:
diff --git a/src/server/shared/DataStores/DB2Store.h b/src/server/shared/DataStores/DB2Store.h
index 72271ce507b..570e8174a39 100644
--- a/src/server/shared/DataStores/DB2Store.h
+++ b/src/server/shared/DataStores/DB2Store.h
@@ -20,6 +20,7 @@
#include "Common.h"
#include "DB2StorageLoader.h"
+#include "DB2SparseStorageLoader.h"
#include "DBStorageIterator.h"
#include "ByteBuffer.h"
@@ -27,7 +28,16 @@
class DB2StorageBase
{
public:
- virtual ~DB2StorageBase() { }
+ DB2StorageBase(char const* fileName, char const* format, HotfixDatabaseStatements preparedStmtIndex)
+ : _tableHash(0), _fileName(fileName), _fieldCount(0), _format(format), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex) { }
+
+ virtual ~DB2StorageBase()
+ {
+ delete[] reinterpret_cast<char*>(_dataTable);
+ delete[] reinterpret_cast<char*>(_dataTableEx);
+ for (char* strings : _stringPool)
+ delete[] strings;
+ }
uint32 GetHash() const { return _tableHash; }
@@ -37,39 +47,20 @@ public:
virtual void EraseRecord(uint32 id) = 0;
-protected:
- uint32 _tableHash;
-};
+ std::string const& GetFileName() const { return _fileName; }
-template<class T>
-class DB2Storage : public DB2StorageBase
-{
- typedef std::list<char*> StringPoolList;
-public:
- typedef DBStorageIterator<T> iterator;
+ uint32 GetFieldCount() const { return _fieldCount; }
- DB2Storage(char const* fileName, char const* format, HotfixDatabaseStatements preparedStmtIndex)
- : _fileName(fileName), _indexTableSize(0), _fieldCount(0), _format(format), _dataTable(nullptr), _dataTableEx(nullptr), _hotfixStatement(preparedStmtIndex)
- {
- _indexTable.AsT = NULL;
- }
+ char const* GetFormat() const { return _format; }
- ~DB2Storage()
- {
- delete[] reinterpret_cast<char*>(_indexTable.AsT);
- delete[] reinterpret_cast<char*>(_dataTable);
- delete[] reinterpret_cast<char*>(_dataTableEx);
- for (char* stringPool : _stringPoolList)
- delete[] stringPool;
- }
+ virtual bool Load(std::string const& path, uint32 locale) = 0;
+ virtual bool LoadStringsFrom(std::string const& path, uint32 locale) = 0;
+ virtual void LoadFromDB() = 0;
+ virtual void LoadStringsFromDB(uint32 locale) = 0;
- bool HasRecord(uint32 id) const override { return id < _indexTableSize && _indexTable.AsT[id] != nullptr; }
- void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const override
+protected:
+ void WriteRecordData(char const* entry, uint32 locale, ByteBuffer& buffer) const
{
- ASSERT(id < _indexTableSize);
- char const* entry = _indexTable.AsChar[id];
- ASSERT(entry);
-
std::size_t fields = strlen(_format);
for (uint32 i = 0; i < fields; ++i)
{
@@ -122,16 +113,48 @@ public:
}
}
+ uint32 _tableHash;
+ std::string _fileName;
+ uint32 _fieldCount;
+ char const* _format;
+ char* _dataTable;
+ char* _dataTableEx;
+ std::vector<char*> _stringPool;
+ HotfixDatabaseStatements _hotfixStatement;
+};
+
+template<class T>
+class DB2Storage : public DB2StorageBase
+{
+ static_assert(std::is_standard_layout<T>::value, "T in DB2Storage must have standard layout.");
+
+public:
+ typedef DBStorageIterator<T> iterator;
+
+ DB2Storage(char const* fileName, char const* format, HotfixDatabaseStatements preparedStmtIndex) : DB2StorageBase(fileName, format, preparedStmtIndex),
+ _indexTableSize(0)
+ {
+ _indexTable.AsT = NULL;
+ }
+
+ ~DB2Storage()
+ {
+ delete[] reinterpret_cast<char*>(_indexTable.AsT);
+ }
+
+ bool HasRecord(uint32 id) const override { return id < _indexTableSize && _indexTable.AsT[id] != nullptr; }
+ void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const override
+ {
+ WriteRecordData(reinterpret_cast<char const*>(AssertEntry(id)), locale, buffer);
+ }
+
void EraseRecord(uint32 id) override { if (id < _indexTableSize) _indexTable.AsT[id] = nullptr; }
T const* LookupEntry(uint32 id) const { return (id >= _indexTableSize) ? nullptr : _indexTable.AsT[id]; }
T const* AssertEntry(uint32 id) const { return ASSERT_NOTNULL(LookupEntry(id)); }
- std::string const& GetFileName() const { return _fileName; }
uint32 GetNumRows() const { return _indexTableSize; }
- char const* GetFormat() const { return _format; }
- uint32 GetFieldCount() const { return _fieldCount; }
- bool Load(std::string const& path, uint32 locale)
+ bool Load(std::string const& path, uint32 locale) override
{
DB2FileLoader db2;
// Check if load was successful, only then continue
@@ -142,23 +165,23 @@ public:
_tableHash = db2.GetHash();
// load raw non-string data
- _dataTable = reinterpret_cast<T*>(db2.AutoProduceData(_format, _indexTableSize, _indexTable.AsChar));
+ _dataTable = db2.AutoProduceData(_format, _indexTableSize, _indexTable.AsChar);
// create string holders for loaded string fields
- if (char* stringHolders = db2.AutoProduceStringsArrayHolders(_format, (char*)_dataTable))
+ if (char* stringHolders = db2.AutoProduceStringsArrayHolders(_format, _dataTable))
{
- _stringPoolList.push_back(stringHolders);
+ _stringPool.push_back(stringHolders);
// load strings from db2 data
- if (char* stringBlock = db2.AutoProduceStrings(_format, (char*)_dataTable, locale))
- _stringPoolList.push_back(stringBlock);
+ if (char* stringBlock = db2.AutoProduceStrings(_format, _dataTable, locale))
+ _stringPool.push_back(stringBlock);
}
// error in db2 file at loading if NULL
return _indexTable.AsT != NULL;
}
- bool LoadStringsFrom(std::string const& path, uint32 locale)
+ bool LoadStringsFrom(std::string const& path, uint32 locale) override
{
// DB2 must be already loaded using Load
if (!_indexTable.AsT)
@@ -171,54 +194,129 @@ public:
// load strings from another locale db2 data
if (DB2FileLoader::GetFormatLocalizedStringFieldCount(_format))
- if (char* stringBlock = db2.AutoProduceStrings(_format, (char*)_dataTable, locale))
- _stringPoolList.push_back(stringBlock);
+ if (char* stringBlock = db2.AutoProduceStrings(_format, _dataTable, locale))
+ _stringPool.push_back(stringBlock);
return true;
}
- void LoadFromDB()
+ void LoadFromDB() override
{
char* extraStringHolders = nullptr;
- if (char* dataTable = DB2DatabaseLoader(_fileName).Load(_format, _hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPoolList))
- _dataTableEx = reinterpret_cast<T*>(dataTable);
-
+ _dataTableEx = DB2DatabaseLoader(_fileName).Load(_format, _hotfixStatement, _indexTableSize, _indexTable.AsChar, extraStringHolders, _stringPool);
if (extraStringHolders)
- _stringPoolList.push_back(extraStringHolders);
+ _stringPool.push_back(extraStringHolders);
}
- void LoadStringsFromDB(uint32 locale)
+ void LoadStringsFromDB(uint32 locale) override
{
if (!DB2FileLoader::GetFormatLocalizedStringFieldCount(_format))
return;
- DB2DatabaseLoader(_fileName).LoadStrings(_format, HotfixDatabaseStatements(_hotfixStatement + 1), locale, _indexTable.AsChar, _stringPoolList);
- }
-
- typedef bool(*SortFunc)(T const* left, T const* right);
-
- void Sort(SortFunc pred)
- {
- ASSERT(strpbrk(_format, "nd") == nullptr, "Only non-indexed storages can be sorted");
- std::sort(_indexTable.AsT, _indexTable.AsT + _indexTableSize, pred);
+ DB2DatabaseLoader(_fileName).LoadStrings(_format, HotfixDatabaseStatements(_hotfixStatement + 1), locale, _indexTable.AsChar, _stringPool);
}
iterator begin() { return iterator(_indexTable.AsT, _indexTableSize); }
iterator end() { return iterator(_indexTable.AsT, _indexTableSize, _indexTableSize); }
private:
- std::string _fileName;
- uint32 _indexTableSize;
- uint32 _fieldCount;
- char const* _format;
union
{
T** AsT;
char** AsChar;
} _indexTable;
- T* _dataTable;
- T* _dataTableEx;
- StringPoolList _stringPoolList;
- HotfixDatabaseStatements _hotfixStatement;
+ uint32 _indexTableSize;
+};
+
+template<class T>
+class DB2SparseStorage : public DB2StorageBase
+{
+ static_assert(std::is_pod<T>::value, "T in DB2SparseStorage must be POD-type.");
+
+public:
+ typedef typename std::unordered_map<uint32, T const*>::const_iterator iterator;
+
+ DB2SparseStorage(char const* fileName, char const* format, HotfixDatabaseStatements preparedStmtIndex)
+ : DB2StorageBase(fileName, format, preparedStmtIndex)
+ {
+ }
+
+ ~DB2SparseStorage()
+ {
+ }
+
+ bool HasRecord(uint32 id) const override { return _indexTable.count(id) > 0; }
+ void WriteRecord(uint32 id, uint32 locale, ByteBuffer& buffer) const override
+ {
+ WriteRecordData(reinterpret_cast<char const*>(AssertEntry(id)), locale, buffer);
+ }
+
+ void EraseRecord(uint32 id) override { _indexTable.erase(id); }
+
+ T const* LookupEntry(uint32 id) const
+ {
+ auto itr = _indexTable.find(id);
+ if (itr != _indexTable.end())
+ return itr->second;
+ return nullptr;
+ }
+
+ T const* AssertEntry(uint32 id) const { return ASSERT_NOTNULL(LookupEntry(id)); }
+
+ uint32 GetNumRows() const { return _indexTable.size(); }
+
+ bool Load(std::string const& path, uint32 locale) override
+ {
+ DB2SparseFileLoader db2;
+ // Check if load was successful, only then continue
+ if (!db2.Load((path + _fileName).c_str()))
+ return false;
+
+ _fieldCount = db2.GetCols();
+ _tableHash = db2.GetHash();
+
+ // load raw non-string data
+ _dataTable = db2.AutoProduceData(_format, IndexTableAdapter<T>(_indexTable), locale, _stringPool);
+
+ // error in db2 file at loading if NULL
+ return !_indexTable.empty();
+ }
+
+ bool LoadStringsFrom(std::string const& path, uint32 locale) override
+ {
+ // DB2 must be already loaded using Load
+ if (_indexTable.empty())
+ return false;
+
+ DB2SparseFileLoader db2;
+ // Check if load was successful, only then continue
+ if (!db2.Load((path + _fileName).c_str()))
+ return false;
+
+ // load strings from another locale db2 data
+ if (DB2SparseFileLoader::GetFormatLocalizedStringFieldCount(_format))
+ if (char* stringBlock = db2.AutoProduceStrings(_format, _dataTable, locale))
+ _stringPool.push_back(stringBlock);
+ return true;
+ }
+
+ void LoadFromDB() override
+ {
+ _dataTableEx = DB2SparseDatabaseLoader(_fileName).Load(_format, _hotfixStatement, IndexTableAdapter<T>(_indexTable), _stringPool);
+ }
+
+ void LoadStringsFromDB(uint32 locale) override
+ {
+ if (!DB2SparseFileLoader::GetFormatLocalizedStringFieldCount(_format))
+ return;
+
+ DB2SparseDatabaseLoader(_fileName).LoadStrings(_format, HotfixDatabaseStatements(_hotfixStatement + 1), locale, IndexTableAdapter<T>(_indexTable), _stringPool);
+ }
+
+ iterator begin() const { return _indexTable.begin(); }
+ iterator end() const { return _indexTable.end(); }
+
+private:
+ std::unordered_map<uint32, T const*> _indexTable;
};
#endif
diff --git a/src/server/shared/DataStores/DBCFileLoader.cpp b/src/server/shared/DataStores/DBCFileLoader.cpp
index 829c3708221..ec3a95f74b9 100644
--- a/src/server/shared/DataStores/DBCFileLoader.cpp
+++ b/src/server/shared/DataStores/DBCFileLoader.cpp
@@ -172,17 +172,6 @@ uint32 DBCFileLoader::GetFormatRecordSize(const char* format, int32* index_pos)
char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**& indexTable, uint32 sqlRecordCount, uint32 sqlHighestIndex, char*& sqlDataTable)
{
- /*
- format STRING, NA, FLOAT, NA, INT <=>
- struct{
- char* field0,
- float field1,
- int field2
- }entry;
-
- this func will generate entry[rows] data;
- */
-
typedef char* ptr;
if (strlen(format) != fieldCount)
return NULL;
@@ -193,11 +182,11 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**
if (i >= 0)
{
- uint32 maxi = 0;
+ int32 maxi = 0;
//find max index
for (uint32 y = 0; y < recordCount; ++y)
{
- uint32 ind = getRecord(y).getUInt(i);
+ int32 ind = int32(getRecord(y).getUInt(i));
if (ind > maxi)
maxi = ind;
}
@@ -224,7 +213,10 @@ char* DBCFileLoader::AutoProduceData(const char* format, uint32& records, char**
for (uint32 y = 0; y < recordCount; ++y)
{
if (i >= 0)
- indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
+ {
+ if (int32(getRecord(y).getUInt(i)) >= 0)
+ indexTable[getRecord(y).getUInt(i)] = &dataTable[offset];
+ }
else
indexTable[y] = &dataTable[offset];
diff --git a/src/server/shared/DataStores/DBStorageIterator.h b/src/server/shared/DataStores/DBStorageIterator.h
index 8148a2a5300..8e7d03f2756 100644
--- a/src/server/shared/DataStores/DBStorageIterator.h
+++ b/src/server/shared/DataStores/DBStorageIterator.h
@@ -35,8 +35,11 @@ public:
}
}
- T* operator->() { return _index[_pos]; }
- T* operator*() { return _index[_pos]; }
+ uint32 Key() const { return _pos; }
+ T const* Value() const { return _index[_pos]; }
+
+ T const* operator->() { return _index[_pos]; }
+ T const* operator*() { return _index[_pos]; }
bool operator==(DBStorageIterator const& right) const { /*ASSERT(_index == right._index, "Iterator belongs to a different container")*/ return _pos == right._pos; }
bool operator!=(DBStorageIterator const& right) const { return !(*this == right); }