diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 34 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStores.cpp | 21 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStores.h | 6 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCStructure.h | 3 | ||||
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Entities/Item/ItemTemplate.h | 26 | ||||
-rw-r--r-- | src/server/game/Globals/ObjectMgr.cpp | 226 | ||||
-rw-r--r-- | src/server/game/Handlers/QuestHandler.cpp | 2 |
8 files changed, 285 insertions, 40 deletions
diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index aca745c52a3..cc310fbdeb5 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -476,6 +476,40 @@ enum ItemLimitCategoryMode ITEM_LIMIT_CATEGORY_MODE_EQUIP = 1 // limit applied to amount equipped items (including used gems) }; +enum ItemSpecStat +{ + ITEM_SPEC_STAT_INTELLECT = 0, + ITEM_SPEC_STAT_AGILITY = 1, + ITEM_SPEC_STAT_STRENGTH = 2, + ITEM_SPEC_STAT_SPIRIT = 3, + ITEM_SPEC_STAT_HIT = 4, + ITEM_SPEC_STAT_DODGE = 5, + ITEM_SPEC_STAT_PARRY = 6, + ITEM_SPEC_STAT_ONE_HANDED_AXE = 7, + ITEM_SPEC_STAT_TWO_HANDED_AXE = 8, + ITEM_SPEC_STAT_ONE_HANDED_SWORD = 9, + ITEM_SPEC_STAT_TWO_HANDED_SWORD = 10, + ITEM_SPEC_STAT_ONE_HANDED_MACE = 11, + ITEM_SPEC_STAT_TWO_HANDED_MACE = 12, + ITEM_SPEC_STAT_DAGGER = 13, + ITEM_SPEC_STAT_FIST_WEAPON = 14, + ITEM_SPEC_STAT_GUN = 15, + ITEM_SPEC_STAT_BOW = 16, + ITEM_SPEC_STAT_CROSSBOW = 17, + ITEM_SPEC_STAT_STAFF = 18, + ITEM_SPEC_STAT_POLEARM = 19, + ITEM_SPEC_STAT_THROWN = 20, + ITEM_SPEC_STAT_WAND = 21, + ITEM_SPEC_STAT_SHIELD = 22, + ITEM_SPEC_STAT_RELIC = 23, + ITEM_SPEC_STAT_CRIT = 24, + ITEM_SPEC_STAT_HASTE = 25, + ITEM_SPEC_STAT_BONUS_ARMOR = 26, + ITEM_SPEC_STAT_CLOAK = 27, + + ITEM_SPEC_STAT_NONE = 28 +}; + enum MountCapabilityFlags { MOUNT_CAPABILITY_FLAG_CAN_PITCH = 0x4, // client checks MOVEMENTFLAG2_FULL_SPEED_PITCHING diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 805885df51c..e1f0c595b5f 100644 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -159,7 +159,7 @@ DBCStorage <ItemSetEntry> sItemSetStore(ItemSetEntryfmt); DBCStorage <ItemSetSpellEntry> sItemSetSpellStore(ItemSetSpellEntryfmt); ItemSetSpellsStore sItemSetSpellsStore; DBCStorage <ItemSpecOverrideEntry> sItemSpecOverrideStore(ItemSpecOverrideEntryfmt); -ItemSpecOverridesStore sItemSpecOverridesStore; +std::unordered_map<uint32, std::vector<ItemSpecOverrideEntry const*>> sItemSpecOverridesStore; DBCStorage <ItemSpecEntry> sItemSpecStore(ItemSpecEntryfmt); DBCStorage <LFGDungeonEntry> sLFGDungeonStore(LFGDungeonEntryfmt); @@ -476,15 +476,13 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc");//19116 LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc");//19116 LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetSpellStore, dbcPath, "ItemSetSpell.dbc");//19116 - for (uint32 i = 0; i < sItemSetSpellStore.GetNumRows(); ++i) - if (ItemSetSpellEntry const* entry = sItemSetSpellStore.LookupEntry(i)) - sItemSetSpellsStore[entry->ItemSetID].push_back(entry); + for (ItemSetSpellEntry const* entry : sItemSetSpellStore) + sItemSetSpellsStore[entry->ItemSetID].push_back(entry); LoadDBC(availableDbcLocales, bad_dbc_files, sItemSpecStore, dbcPath, "ItemSpec.dbc");//19116 LoadDBC(availableDbcLocales, bad_dbc_files, sItemSpecOverrideStore, dbcPath, "ItemSpecOverride.dbc");//19116 - for (uint32 i = 0; i < sItemSpecOverrideStore.GetNumRows(); ++i) - if (ItemSpecOverrideEntry const* entry = sItemSpecOverrideStore.LookupEntry(i)) - sItemSpecOverridesStore[entry->ItemID].push_back(entry); + for (ItemSpecOverrideEntry const* entry : sItemSpecOverrideStore) + sItemSpecOverridesStore[entry->ItemID].push_back(entry); LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorQualityStore, dbcPath, "ItemArmorQuality.dbc");//19116 LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorShieldStore, dbcPath, "ItemArmorShield.dbc");//19116 @@ -1073,3 +1071,12 @@ std::vector<SpecializationSpellsEntry const*> const* GetSpecializationSpells(uin return nullptr; } + +std::vector<ItemSpecOverrideEntry const*> const* GetItemSpecOverrides(uint32 itemId) +{ + auto itr = sItemSpecOverridesStore.find(itemId); + if (itr != sItemSpecOverridesStore.end()) + return &itr->second; + + return nullptr; +} diff --git a/src/server/game/DataStores/DBCStores.h b/src/server/game/DataStores/DBCStores.h index 781b981c4c1..72c0c35f1cb 100644 --- a/src/server/game/DataStores/DBCStores.h +++ b/src/server/game/DataStores/DBCStores.h @@ -23,9 +23,6 @@ #include "DBCStructure.h" #include "SharedDefines.h" -typedef std::map<uint32, uint32> SpecializationOverrideSpellsList; -typedef std::map<uint32, SpecializationOverrideSpellsList> SpecializationOverrideSpellsMap; - typedef std::list<uint32> SimpleFactionsList; SimpleFactionsList const* GetFactionTeamList(uint32 faction); @@ -45,6 +42,8 @@ uint32 GetVirtualMapForMapAndZone(uint32 mapid, uint32 zoneId); std::string const& GetRandomCharacterName(uint8 race, uint8 gender); +std::vector<ItemSpecOverrideEntry const*> const* GetItemSpecOverrides(uint32 itemId); + enum ContentLevels { CONTENT_1_60 = 0, @@ -212,7 +211,6 @@ extern DBCStorage <ItemSetEntry> sItemSetStore; extern DBCStorage <ItemSetSpellEntry> sItemSetSpellStore; extern ItemSetSpellsStore sItemSetSpellsStore; extern DBCStorage <ItemSpecOverrideEntry> sItemSpecOverrideStore; -extern ItemSpecOverridesStore sItemSpecOverridesStore; extern DBCStorage <ItemSpecEntry> sItemSpecStore; extern DBCStorage <LFGDungeonEntry> sLFGDungeonStore; extern DBCStorage <LiquidTypeEntry> sLiquidTypeStore; diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index ae6722b7932..fd6047a8adf 100644 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -1126,9 +1126,6 @@ struct ItemSpecOverrideEntry uint32 SpecID; // 2 }; -typedef std::vector<ItemSpecOverrideEntry const*> ItemSpecOverrides; -typedef std::unordered_map<uint32, ItemSpecOverrides> ItemSpecOverridesStore; - struct LFGDungeonEntry { uint32 ID; // 0 diff --git a/src/server/game/Entities/Item/ItemTemplate.cpp b/src/server/game/Entities/Item/ItemTemplate.cpp index 10d8272fca8..a21a4f1aa3f 100644 --- a/src/server/game/Entities/Item/ItemTemplate.cpp +++ b/src/server/game/Entities/Item/ItemTemplate.cpp @@ -140,7 +140,8 @@ void ItemTemplate::GetDamage(uint32 itemLevel, float& minDamage, float& maxDamag bool ItemTemplate::CanWinForPlayer(Player const* player) const { - if (!Specializations.size()) + std::unordered_set<uint32> const& specs = Specializations[player->getLevel() > 40]; + if (specs.empty()) return true; uint32 spec = player->GetSpecId(player->GetActiveTalentGroup()); @@ -150,6 +151,6 @@ bool ItemTemplate::CanWinForPlayer(Player const* player) const if (!spec) return false; - UsableTalentSpecs::const_iterator itr = Specializations.find(spec); - return itr != Specializations.end(); + auto itr = specs.find(spec); + return itr != specs.end(); } diff --git a/src/server/game/Entities/Item/ItemTemplate.h b/src/server/game/Entities/Item/ItemTemplate.h index 9ab04727ced..47523872151 100644 --- a/src/server/game/Entities/Item/ItemTemplate.h +++ b/src/server/game/Entities/Item/ItemTemplate.h @@ -59,6 +59,9 @@ enum ItemModType ITEM_MOD_EXPERTISE_RATING = 37, ITEM_MOD_ATTACK_POWER = 38, ITEM_MOD_RANGED_ATTACK_POWER = 39, + ITEM_MOD_VERSATILITY = 40, + ITEM_MOD_SPELL_HEALING_DONE = 41, + ITEM_MOD_SPELL_DAMAGE_DONE = 42, ITEM_MOD_MANA_REGENERATION = 43, ITEM_MOD_ARMOR_PENETRATION_RATING = 44, ITEM_MOD_SPELL_POWER = 45, @@ -73,10 +76,26 @@ enum ItemModType ITEM_MOD_SHADOW_RESISTANCE = 54, ITEM_MOD_NATURE_RESISTANCE = 55, ITEM_MOD_ARCANE_RESISTANCE = 56, + ITEM_MOD_PVP_POWER = 57, + ITEM_MOD_CR_AMPLIFY = 58, + ITEM_MOD_CR_MULTISTRIKE = 59, + ITEM_MOD_CR_READINESS = 60, + ITEM_MOD_CR_SPEED = 61, + ITEM_MOD_CR_LIFESTEAL = 62, + ITEM_MOD_CR_AVOIDANCE = 63, + ITEM_MOD_CR_STURDINESS = 64, + ITEM_MOD_CR_UNUSED_7 = 65, + ITEM_MOD_CR_CLEAVE = 66, + ITEM_MOD_CR_UNUSED_9 = 67, + ITEM_MOD_CR_UNUSED_10 = 68, + ITEM_MOD_CR_UNUSED_11 = 69, + ITEM_MOD_CR_UNUSED_12 = 70, + ITEM_MOD_AGI_STR_INT = 71, + ITEM_MOD_AGI_STR = 72, + ITEM_MOD_AGI_INT = 73, + ITEM_MOD_STR_INT = 74 }; -#define MAX_ITEM_MOD 57 - enum ItemSpelltriggerType { ITEM_SPELLTRIGGER_ON_USE = 0, // use after equip cooldown @@ -585,7 +604,6 @@ const uint32 MaxItemSubclassValues[MAX_ITEM_CLASS] = #define MAX_ITEM_LEVEL 1000 class Player; -typedef std::set<uint32> UsableTalentSpecs; struct ItemTemplate { @@ -658,7 +676,7 @@ struct ItemTemplate uint32 MaxMoneyLoot; uint32 FlagsCu; float SpellPPMRate; - UsableTalentSpecs Specializations; + std::unordered_set<uint32> Specializations[2]; // one set for 1-40 level range and another for 41-100 // helpers bool CanChangeEquipStateInCombat() const diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 43371c5aff8..83410fb477b 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -2415,6 +2415,183 @@ void FillDisenchantFields(uint32* disenchantID, uint32* requiredDisenchantSkill, } } +struct ItemSpecStats +{ + uint32 ItemType; + uint32 ItemSpecStatTypes[MAX_ITEM_PROTO_STATS]; + uint32 ItemSpecStatCount; + + ItemSpecStats(ItemEntry const* item, ItemSparseEntry const* sparse) : ItemType(0), ItemSpecStatCount(0) + { + memset(ItemSpecStatTypes, -1, sizeof(ItemSpecStatTypes)); + + if (item->Class == ITEM_CLASS_WEAPON) + { + ItemType = 5; + switch (item->SubClass) + { + case ITEM_SUBCLASS_WEAPON_AXE: + AddStat(ITEM_SPEC_STAT_ONE_HANDED_AXE); + break; + case ITEM_SUBCLASS_WEAPON_AXE2: + AddStat(ITEM_SPEC_STAT_TWO_HANDED_AXE); + break; + case ITEM_SUBCLASS_WEAPON_BOW: + AddStat(ITEM_SPEC_STAT_BOW); + break; + case ITEM_SUBCLASS_WEAPON_GUN: + AddStat(ITEM_SPEC_STAT_GUN); + break; + case ITEM_SUBCLASS_WEAPON_MACE: + AddStat(ITEM_SPEC_STAT_ONE_HANDED_MACE); + break; + case ITEM_SUBCLASS_WEAPON_MACE2: + AddStat(ITEM_SPEC_STAT_TWO_HANDED_MACE); + break; + case ITEM_SUBCLASS_WEAPON_POLEARM: + AddStat(ITEM_SPEC_STAT_POLEARM); + break; + case ITEM_SUBCLASS_WEAPON_SWORD: + AddStat(ITEM_SPEC_STAT_ONE_HANDED_SWORD); + break; + case ITEM_SUBCLASS_WEAPON_SWORD2: + AddStat(ITEM_SPEC_STAT_TWO_HANDED_SWORD); + break; + case ITEM_SUBCLASS_WEAPON_STAFF: + AddStat(ITEM_SPEC_STAT_STAFF); + break; + case ITEM_SUBCLASS_WEAPON_FIST_WEAPON: + AddStat(ITEM_SPEC_STAT_FIST_WEAPON); + break; + case ITEM_SUBCLASS_WEAPON_DAGGER: + AddStat(ITEM_SPEC_STAT_DAGGER); + break; + case ITEM_SUBCLASS_WEAPON_THROWN: + AddStat(ITEM_SPEC_STAT_THROWN); + break; + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + AddStat(ITEM_SPEC_STAT_CROSSBOW); + break; + case ITEM_SUBCLASS_WEAPON_WAND: + AddStat(ITEM_SPEC_STAT_WAND); + break; + default: + break; + } + } + else if (item->Class == ITEM_CLASS_ARMOR && item->SubClass > 5 && item->SubClass <= 11) + { + switch (item->SubClass) + { + case ITEM_SUBCLASS_ARMOR_CLOTH: + if (sparse->InventoryType != INVTYPE_CLOAK) + { + ItemType = 1; + break; + } + + ItemType = 0; + AddStat(ITEM_SPEC_STAT_CLOAK); + break; + case ITEM_SUBCLASS_ARMOR_LEATHER: + ItemType = 2; + break; + case ITEM_SUBCLASS_ARMOR_MAIL: + ItemType = 3; + break; + case ITEM_SUBCLASS_ARMOR_PLATE: + ItemType = 4; + break; + default: + ItemType = 6; + if (item->SubClass == ITEM_SUBCLASS_ARMOR_SHIELD) + AddStat(ITEM_SPEC_STAT_SHIELD); + else if (item->SubClass > ITEM_SUBCLASS_ARMOR_SHIELD && item->SubClass <= ITEM_SUBCLASS_ARMOR_RELIC) + AddStat(ITEM_SPEC_STAT_RELIC); + break; + } + } + else + ItemType = 0; + + for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i) + if (sparse->ItemStatType[i] != -1) + AddModStat(sparse->ItemStatType[i]); + } + + void AddStat(ItemSpecStat statType) + { + if (ItemSpecStatCount >= MAX_ITEM_PROTO_STATS) + return; + + for (uint32 i = 0; i < MAX_ITEM_PROTO_STATS; ++i) + if (ItemSpecStatTypes[i] == uint32(statType)) + return; + + ItemSpecStatTypes[ItemSpecStatCount++] = statType; + } + + void AddModStat(int32 itemStatType) + { + switch (itemStatType) + { + case ITEM_MOD_AGILITY: + AddStat(ITEM_SPEC_STAT_AGILITY); + break; + case ITEM_MOD_STRENGTH: + AddStat(ITEM_SPEC_STAT_STRENGTH); + break; + case ITEM_MOD_INTELLECT: + AddStat(ITEM_SPEC_STAT_INTELLECT); + break; + case ITEM_MOD_SPIRIT: + AddStat(ITEM_SPEC_STAT_SPIRIT); + break; + case ITEM_MOD_DODGE_RATING: + AddStat(ITEM_SPEC_STAT_DODGE); + break; + case ITEM_MOD_PARRY_RATING: + AddStat(ITEM_SPEC_STAT_PARRY); + break; + case ITEM_MOD_CRIT_MELEE_RATING: + case ITEM_MOD_CRIT_RANGED_RATING: + case ITEM_MOD_CRIT_SPELL_RATING: + case ITEM_MOD_CRIT_RATING: + AddStat(ITEM_SPEC_STAT_CRIT); + break; + case ITEM_MOD_HASTE_MELEE_RATING: + case ITEM_MOD_HASTE_RANGED_RATING: + case ITEM_MOD_HASTE_SPELL_RATING: + case ITEM_MOD_HASTE_RATING: + AddStat(ITEM_SPEC_STAT_HASTE); + break; + case ITEM_MOD_HIT_RATING: + AddStat(ITEM_SPEC_STAT_HIT); + break; + case ITEM_MOD_EXTRA_ARMOR: + AddStat(ITEM_SPEC_STAT_BONUS_ARMOR); + break; + case ITEM_MOD_AGI_STR_INT: + AddStat(ITEM_SPEC_STAT_AGILITY); + AddStat(ITEM_SPEC_STAT_STRENGTH); + AddStat(ITEM_SPEC_STAT_INTELLECT); + break; + case ITEM_MOD_AGI_STR: + AddStat(ITEM_SPEC_STAT_AGILITY); + AddStat(ITEM_SPEC_STAT_STRENGTH); + break; + case ITEM_MOD_AGI_INT: + AddStat(ITEM_SPEC_STAT_AGILITY); + AddStat(ITEM_SPEC_STAT_INTELLECT); + break; + case ITEM_MOD_STR_INT: + AddStat(ITEM_SPEC_STAT_STRENGTH); + AddStat(ITEM_SPEC_STAT_INTELLECT); + break; + } + } +}; + void ObjectMgr::LoadItemTemplates() { uint32 oldMSTime = getMSTime(); @@ -2440,28 +2617,41 @@ void ObjectMgr::LoadItemTemplates() itemTemplate.FlagsCu = 0; itemTemplate.SpellPPMRate = 0.0f; - /*for (uint32 i = 0; i < sItemSpecStore.GetNumRows(); ++i) + if (std::vector<ItemSpecOverrideEntry const*> const* itemSpecOverrides = GetItemSpecOverrides(sparse->ID)) + { + for (ItemSpecOverrideEntry const* itemSpecOverride : *itemSpecOverrides) + itemTemplate.Specializations[0].insert(itemSpecOverride->SpecID); + + itemTemplate.Specializations[1] = itemTemplate.Specializations[0]; + } + else { - if (ItemSpecEntry const* spec = sItemSpecStore.LookupEntry(i)) + ItemSpecStats itemSpecStats(db2Data, sparse); + + if (itemSpecStats.ItemSpecStatCount) { - if (itemTemplate.GetBaseItemLevel() >= spec->MinLevel && itemTemplate.GetBaseItemLevel() <= spec->MaxLevel) + for (ItemSpecEntry const* itemSpec : sItemSpecStore) { - // have to research what are these! - if (spec->PrimaryStat && spec->SecondaryStat && spec->ItemType) + if (itemSpecStats.ItemType != itemSpec->ItemType) + continue; + + bool hasPrimary = false; + bool hasSecondary = itemSpec->SecondaryStat == ITEM_SPEC_STAT_NONE; + for (uint32 i = 0; i < itemSpecStats.ItemSpecStatCount; ++i) { - itemTemplate.Specializations.insert(spec->SpecID); + if (itemSpecStats.ItemSpecStatTypes[i] == itemSpec->PrimaryStat) + hasPrimary = true; + if (itemSpecStats.ItemSpecStatTypes[i] == itemSpec->SecondaryStat) + hasSecondary = true; } - } - } - }*/ - ItemSpecOverridesStore::const_iterator spec = sItemSpecOverridesStore.find(itemTemplate.GetId()); - if (spec != sItemSpecOverridesStore.end()) - { - itemTemplate.Specializations.clear(); - for (ItemSpecOverrideEntry const* over : (*spec).second) - { - itemTemplate.Specializations.insert(over->SpecID); + if (!hasPrimary || !hasSecondary) + continue; + + if (ChrSpecializationEntry const* specialization = sChrSpecializationStore.LookupEntry(itemSpec->SpecID)) + if ((1 << (specialization->ClassID - 1)) & sparse->AllowableClass) + itemTemplate.Specializations[itemSpec->MaxLevel > 40].insert(itemSpec->SpecID); + } } } @@ -5355,7 +5545,7 @@ void ObjectMgr::LoadQuestGreetings() _questGreetingStore.clear(); // need for reload case - // 0 1 2 3 + // 0 1 2 3 QueryResult result = WorldDatabase.Query("SELECT ID, type, GreetEmoteType, GreetEmoteDelay, Greeting FROM quest_greeting"); if (!result) { @@ -5372,7 +5562,7 @@ void ObjectMgr::LoadQuestGreetings() uint32 id = fields[0].GetUInt32(); uint8 type = fields[1].GetUInt8(); // overwrite - switch (type) + switch (type) { case 0: // Creature type = TYPEID_UNIT; diff --git a/src/server/game/Handlers/QuestHandler.cpp b/src/server/game/Handlers/QuestHandler.cpp index d7ad9c71956..9d5e403bde0 100644 --- a/src/server/game/Handlers/QuestHandler.cpp +++ b/src/server/game/Handlers/QuestHandler.cpp @@ -263,7 +263,7 @@ void WorldSession::HandleQuestgiverChooseRewardOpcode(WorldPackets::Quest::Quest } } - if (quest->GetQuestPackageID()) + if (!itemValid && quest->GetQuestPackageID()) { if (std::vector<QuestPackageItemEntry const*> const* questPackageItems = sDB2Manager.GetQuestPackageItems(quest->GetQuestPackageID())) { |