diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/server/game/DataStores/DBCStores.cpp | 160 | ||||
| -rwxr-xr-x | src/server/game/DataStores/DBCStructure.h | 98 | ||||
| -rwxr-xr-x | src/server/game/DataStores/DBCfmt.h | 2 | ||||
| -rwxr-xr-x | src/server/game/Entities/Item/ItemPrototype.h | 4 | ||||
| -rwxr-xr-x | src/server/game/Entities/Player/Player.cpp | 59 | ||||
| -rwxr-xr-x | src/server/game/Server/Protocol/Handlers/ItemHandler.cpp | 2 |
6 files changed, 200 insertions, 125 deletions
diff --git a/src/server/game/DataStores/DBCStores.cpp b/src/server/game/DataStores/DBCStores.cpp index 82910d296af..ceba8d178cf 100755 --- a/src/server/game/DataStores/DBCStores.cpp +++ b/src/server/game/DataStores/DBCStores.cpp @@ -397,7 +397,7 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sItemRandomSuffixStore, dbcPath, "ItemRandomSuffix.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sItemSetStore, dbcPath, "ItemSet.dbc");//14545 - + LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorQualityStore, dbcPath, "ItemArmorQuality.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorShieldStore, dbcPath, "ItemArmorShield.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sItemArmorTotalStore, dbcPath, "ItemArmorTotal.dbc");//14545 @@ -487,7 +487,7 @@ void LoadDBCStores(const std::string& dataPath) } } - + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellReagentsStore, dbcPath,"SpellReagents.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sSpellScalingStore, dbcPath,"SpellScaling.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sSpellTotemsStore, dbcPath,"SpellTotems.dbc");//14545 @@ -501,10 +501,10 @@ void LoadDBCStores(const std::string& dataPath) LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraOptionsStore, dbcPath,"SpellAuraOptions.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sSpellAuraRestrictionsStore, dbcPath,"SpellAuraRestrictions.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCastingRequirementsStore, dbcPath,"SpellCastingRequirements.dbc");//14545 - + LoadDBC(availableDbcLocales, bad_dbc_files, sSpellCategoriesStore, dbcPath,"SpellCategories.dbc");//14545 LoadDBC(availableDbcLocales, bad_dbc_files, sSpellEffectStore, dbcPath,"SpellEffect.dbc");//14545 - + for(uint32 i = 1; i < sSpellEffectStore.GetNumRows(); ++i) { if(SpellEffectEntry const *spellEffect = sSpellEffectStore.LookupEntry(i)) @@ -975,6 +975,158 @@ uint32 const* GetTalentTabPages(uint8 cls) return sTalentTabPages[cls]; } +uint32 ScalingStatValuesEntry::GetStatMultiplier(uint32 inventoryType) const +{ + if (inventoryType < MAX_INVTYPE) + { + switch (inventoryType) + { + case INVTYPE_NON_EQUIP: + case INVTYPE_BODY: + case INVTYPE_BAG: + case INVTYPE_TABARD: + case INVTYPE_AMMO: + case INVTYPE_QUIVER: + return 0; + case INVTYPE_HEAD: + case INVTYPE_CHEST: + case INVTYPE_LEGS: + case INVTYPE_2HWEAPON: + case INVTYPE_ROBE: + return StatMultiplier[0]; + case INVTYPE_SHOULDERS: + case INVTYPE_WAIST: + case INVTYPE_FEET: + case INVTYPE_HANDS: + case INVTYPE_TRINKET: + return StatMultiplier[1]; + case INVTYPE_NECK: + case INVTYPE_WRISTS: + case INVTYPE_FINGER: + case INVTYPE_SHIELD: + case INVTYPE_CLOAK: + case INVTYPE_HOLDABLE: + return StatMultiplier[2]; + case INVTYPE_RANGED: + case INVTYPE_THROWN: + case INVTYPE_RANGEDRIGHT: + case INVTYPE_RELIC: + return StatMultiplier[3]; + case INVTYPE_WEAPON: + case INVTYPE_WEAPONMAINHAND: + case INVTYPE_WEAPONOFFHAND: + return StatMultiplier[4]; + default: + break; + } + } + return 0; +} + +uint32 ScalingStatValuesEntry::GetArmor(uint32 inventoryType, uint32 armorType) const +{ + if (inventoryType <= INVTYPE_ROBE && armorType < 4) + { + switch (inventoryType) + { + case INVTYPE_NON_EQUIP: + case INVTYPE_NECK: + case INVTYPE_BODY: + case INVTYPE_FINGER: + case INVTYPE_TRINKET: + case INVTYPE_WEAPON: + case INVTYPE_SHIELD: + case INVTYPE_RANGED: + case INVTYPE_2HWEAPON: + case INVTYPE_BAG: + case INVTYPE_TABARD: + break; + case INVTYPE_SHOULDERS: + return Armor[0][armorType]; + case INVTYPE_CHEST: + case INVTYPE_ROBE: + return Armor[1][armorType]; + case INVTYPE_HEAD: + return Armor[2][armorType]; + case INVTYPE_LEGS: + return Armor[3][armorType]; + case INVTYPE_FEET: + return Armor[4][armorType]; + case INVTYPE_WAIST: + return Armor[5][armorType]; + case INVTYPE_HANDS: + return Armor[6][armorType]; + case INVTYPE_WRISTS: + return Armor[7][armorType]; + case INVTYPE_CLOAK: + return CloakArmor; + default: + break; + } + } + return 0; +} + +uint32 ScalingStatValuesEntry::GetDPSAndDamageMultiplier(uint32 subClass, bool isCasterWeapon, float* damageMultiplier) const +{ + if (!isCasterWeapon) + { + switch (subClass) + { + case ITEM_SUBCLASS_WEAPON_AXE: + case ITEM_SUBCLASS_WEAPON_MACE: + case ITEM_SUBCLASS_WEAPON_SWORD: + case ITEM_SUBCLASS_WEAPON_DAGGER: + case ITEM_SUBCLASS_WEAPON_THROWN: + *damageMultiplier = 0.3f; + return dpsMod[0]; + case ITEM_SUBCLASS_WEAPON_AXE2: + case ITEM_SUBCLASS_WEAPON_MACE2: + case ITEM_SUBCLASS_WEAPON_POLEARM: + case ITEM_SUBCLASS_WEAPON_SWORD2: + case ITEM_SUBCLASS_WEAPON_STAFF: + case ITEM_SUBCLASS_WEAPON_FISHING_POLE: + *damageMultiplier = 0.2f; + return dpsMod[1]; + case ITEM_SUBCLASS_WEAPON_BOW: + case ITEM_SUBCLASS_WEAPON_GUN: + case ITEM_SUBCLASS_WEAPON_CROSSBOW: + *damageMultiplier = 0.3f; + return dpsMod[4]; + case ITEM_SUBCLASS_WEAPON_obsolete: + case ITEM_SUBCLASS_WEAPON_EXOTIC: + case ITEM_SUBCLASS_WEAPON_EXOTIC2: + case ITEM_SUBCLASS_WEAPON_FIST: + case ITEM_SUBCLASS_WEAPON_MISC: + case ITEM_SUBCLASS_WEAPON_SPEAR: + case ITEM_SUBCLASS_WEAPON_WAND: + break; + } + } + else + { + if (subClass <= ITEM_SUBCLASS_WEAPON_WAND) + { + uint32 mask = 1 << subClass; + // two-handed weapons + if (mask & 0x562) + { + *damageMultiplier = 0.2f; + return dpsMod[3]; + } + + if (mask & (1 << ITEM_SUBCLASS_WEAPON_WAND)) + { + *damageMultiplier = 0.3f; + return dpsMod[5]; + } + } + *damageMultiplier = 0.3f; + return dpsMod[2]; + } + return 0; +} + // script support functions DBCStorage <SoundEntriesEntry> const* GetSoundEntriesStore() { return &sSoundEntriesStore; } DBCStorage <SpellRangeEntry> const* GetSpellRangeStore() { return &sSpellRangeStore; } diff --git a/src/server/game/DataStores/DBCStructure.h b/src/server/game/DataStores/DBCStructure.h index 6af4504f52a..6f303c23c4a 100755 --- a/src/server/game/DataStores/DBCStructure.h +++ b/src/server/game/DataStores/DBCStructure.h @@ -520,7 +520,7 @@ struct AchievementCriteriaEntry //uint32 unk1; // 15 only one value, still unknown //uint32 unk2; // 16 all zeros //uint32 moreRequirement[3]; // 17-19 - //uint32 moreRequirementValue[3]; // 20-22 + //uint32 moreRequirementValue[3]; // 20-22 }; struct AreaTableEntry @@ -1481,91 +1481,17 @@ struct ScalingStatDistributionEntry struct ScalingStatValuesEntry { - uint32 Id; // 0 - uint32 Level; // 1 - uint32 dpsMod[6]; // 2-7 DPS mod for level - uint32 spellBonus; // 8 spell power for level - uint32 ssdMultiplier[5]; // 9-13 Multiplier for ScalingStatDistribution - uint32 armorMod[4]; // 14-17 Armor for level - uint32 armorMod2[4]; // 18-21 Armor for level - //uint32 trash[24]; // 22-45 - //uint32 unk2; // 46 unk, probably also Armor for level (flag 0x80000?) - - uint32 getssdMultiplier(uint32 mask) const - { - if (mask & 0x4001F) - { - if (mask & 0x00000001) - return ssdMultiplier[1]; - if (mask & 0x00000002) - return ssdMultiplier[2]; // 0 and 1 were duplicated - if (mask & 0x00000004) - return ssdMultiplier[3]; - if (mask & 0x00000008) - return ssdMultiplier[0]; - if (mask & 0x00000010) - return ssdMultiplier[4]; - if (mask & 0x00040000) - return ssdMultiplier[2]; // 4.0.0 - } - return 0; - } - - uint32 getArmorMod(uint32 mask) const - { - if (mask & 0x00F001E0) - { - if (mask & 0x00000020) - return armorMod[0]; - if (mask & 0x00000040) - return armorMod[1]; - if (mask & 0x00000080) - return armorMod[2]; - if (mask & 0x00000100) - return armorMod[3]; - - if (mask & 0x00100000) - return armorMod2[0]; // cloth - if (mask & 0x00200000) - return armorMod2[1]; // leather - if (mask & 0x00400000) - return armorMod2[2]; // mail - if (mask & 0x00800000) - return armorMod2[3]; // plate - } - return 0; - } - uint32 getDPSMod(uint32 mask) const - { - if (mask&0x7E00) - { - if (mask & 0x00000200) - return dpsMod[0]; - if (mask & 0x00000400) - return dpsMod[1]; - if (mask & 0x00000800) - return dpsMod[2]; - if (mask & 0x00001000) - return dpsMod[3]; - if (mask & 0x00002000) - return dpsMod[4]; - if (mask & 0x00004000) - return dpsMod[5]; // not used? - } - return 0; - } - uint32 getSpellBonus(uint32 mask) const - { - if (mask & 0x00008000) - return spellBonus; - return 0; - } - uint32 getFeralBonus(uint32 mask) const // removed in 3.2.x? - { - if (mask & 0x00010000) - return 0; // not used? - return 0; - } + uint32 Id; // 0 + uint32 Level; // 1 + uint32 dpsMod[6]; // 2-7 DPS mod for level + uint32 Spellpower; // 8 spell power for level + uint32 StatMultiplier[5]; // 9-13 Multiplier for ScalingStatDistribution + uint32 Armor[8][4]; // 14-46 Armor for level + uint32 CloakArmor; // 47 armor for cloak + + uint32 GetStatMultiplier(uint32 inventoryType) const; + uint32 GetArmor(uint32 inventoryType, uint32 armorType) const; + uint32 GetDPSAndDamageMultiplier(uint32 subClass, bool isCasterWeapon, float* damageMultiplier) const; }; //struct SkillLineCategoryEntry{ diff --git a/src/server/game/DataStores/DBCfmt.h b/src/server/game/DataStores/DBCfmt.h index eb62a211067..be2fe6916e4 100755 --- a/src/server/game/DataStores/DBCfmt.h +++ b/src/server/game/DataStores/DBCfmt.h @@ -105,7 +105,7 @@ const char QuestFactionRewardfmt[]="niiiiiiiiii"; const char PvPDifficultyfmt[]="diiiii"; const char RandomPropertiesPointsfmt[]="niiiiiiiiiiiiiii"; const char ScalingStatDistributionfmt[]="niiiiiiiiiiiiiiiiiiiixi"; -const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiixxxxxxxxxxxxxxxxxxxxxxxxx"; +const char ScalingStatValuesfmt[]="iniiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii"; const char SkillLinefmt[]="nisxixi"; const char SkillLineAbilityfmt[]="niiiixxiiiiixx"; const char SoundEntriesfmt[]="nxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; diff --git a/src/server/game/Entities/Item/ItemPrototype.h b/src/server/game/Entities/Item/ItemPrototype.h index 03212c129fd..c15189dfb5f 100755 --- a/src/server/game/Entities/Item/ItemPrototype.h +++ b/src/server/game/Entities/Item/ItemPrototype.h @@ -189,7 +189,8 @@ enum ItemFlagsExtra ITEM_FLAGS_EXTRA_HORDE_ONLY = 0x00000001, ITEM_FLAGS_EXTRA_ALLIANCE_ONLY = 0x00000002, ITEM_FLAGS_EXTRA_EXT_COST_REQUIRES_GOLD = 0x00000004, // when item uses extended cost, gold is also required - ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100 + ITEM_FLAGS_EXTRA_NEED_ROLL_DISABLED = 0x00000100, + ITEM_FLAGS_EXTRA_CASTER_WEAPON = 0x00000200, }; enum BAG_FAMILY_MASK @@ -608,7 +609,6 @@ struct ItemTemplate uint32 StatsCount; _ItemStat ItemStat[MAX_ITEM_PROTO_STATS]; uint32 ScalingStatDistribution; // id from ScalingStatDistribution.dbc - uint32 ScalingStatValue; // mask for selecting column in ScalingStatValues.dbc _Damage Damage[MAX_ITEM_PROTO_DAMAGES]; uint32 Armor; uint32 HolyRes; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 4550f9c6e58..b444a8fdc94 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -1881,7 +1881,7 @@ bool Player::BuildEnumData(QueryResult result, ByteBuffer* data) if (result && !(playerFlags & PLAYER_FLAGS_GHOST) && (plrClass == CLASS_WARLOCK || plrClass == CLASS_HUNTER || plrClass == CLASS_DEATH_KNIGHT)) { uint32 entry = fields[16].GetUInt32(); - CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry); + CreatureTemplate const* creatureInfo = sObjectMgr->GetCreatureTemplate(entry); if (creatureInfo) { petDisplayId = fields[17].GetUInt32(); @@ -1917,7 +1917,7 @@ bool Player::BuildEnumData(QueryResult result, ByteBuffer* data) if (Guid3) *data << uint8(Guid3^1); - + //*data << uint8(2); // unk, bit 14 uint32 playerBytes2 = fields[6].GetUInt32(); @@ -1956,29 +1956,29 @@ bool Player::BuildEnumData(QueryResult result, ByteBuffer* data) *data << uint8(Guid2^1); *data << uint32(petDisplayId); // Pet DisplayID - + //if (uint8(GuildGuid >> 56)) // *data << uint8(GuildGuid^1 >> 56); - + *data << uint8(level); // Level *data << uint8(playerBytes >> 16); // Hair style - + //if (uint8(GuildGuid >> 16)) // *data << uint8(GuildGuid^1 >> 16); - + *data << uint8(plrRace); // Race *data << uint8(playerBytes >> 24); // Hair color //if (uint8(GuildGuid >> 48)) // *data << uint8(GuildGuid^1 >> 48); - + *data << uint8(gender); // Gender //if (uint8(GuildGuid >> 24)) // *data << uint8(GuildGuid^1 >> 24); - + *data << uint8(0); // character order id (used for char list positioning) TODO: implement - + Tokens equipment(fields[19].GetString(), ' '); for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot) { @@ -1993,7 +1993,7 @@ bool Player::BuildEnumData(QueryResult result, ByteBuffer* data) *data << uint32(0); continue; } - + SpellItemEnchantmentEntry const *enchant = NULL; uint32 enchants = GetUInt32ValueFromArray(equipment, visualbase + 1); for (uint8 enchantSlot = PERM_ENCHANTMENT_SLOT; enchantSlot <= TEMP_ENCHANTMENT_SLOT; ++enchantSlot) @@ -2032,7 +2032,7 @@ bool Player::BuildEnumData(QueryResult result, ByteBuffer* data) else *data << uint32(CHAR_CUSTOMIZE_FLAG_NONE); - + //if (uint8(GuildGuid >> 8)) // *data << uint8(GuildGuid^1 >> 8); @@ -7875,7 +7875,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (ssd && ssd_level > ssd->MaxLevel) ssd_level = ssd->MaxLevel; - ScalingStatValuesEntry const* ssv = proto->ScalingStatValue ? sScalingStatValuesStore.LookupEntry(ssd_level) : NULL; + ScalingStatValuesEntry const* ssv = ssd ? sScalingStatValuesStore.LookupEntry(ssd_level) : NULL; if (only_level_scale && !ssv) return; @@ -7889,7 +7889,7 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (ssd->StatMod[i] < 0) continue; statType = ssd->StatMod[i]; - val = (ssv->getssdMultiplier(proto->ScalingStatValue) * ssd->Modifier[i]) / 10000; + val = (ssv->GetStatMultiplier(proto->InventoryType) * ssd->Modifier[i]) / 10000; } else { @@ -8054,15 +8054,14 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply } // Apply Spell Power from ScalingStatValue if set - if (ssv) - if (int32 spellbonus = ssv->getSpellBonus(proto->ScalingStatValue)) + if (ssv && proto->Flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON) + if (int32 spellbonus = int32(ssv->Spellpower)) ApplySpellPowerBonus(spellbonus, apply); // If set ScalingStatValue armor get it or use item armor uint32 armor = proto->Armor; - if (ssv) - if (uint32 ssvarmor = ssv->getArmorMod(proto->ScalingStatValue)) - armor = ssvarmor; + if (ssv && proto->Class == ITEM_CLASS_ARMOR) + armor = ssv->GetArmor(proto->InventoryType, proto->SubClass - 1); if (armor) { @@ -8124,15 +8123,6 @@ void Player::_ApplyItemBonuses(ItemTemplate const* proto, uint8 slot, bool apply if (CanUseAttackType(attType)) _ApplyWeaponDamage(slot, proto, ssv, apply); - // Apply feral bonus from ScalingStatValue if set - if (ssv) - if (int32 feral_bonus = ssv->getFeralBonus(proto->ScalingStatValue)) - ApplyFeralAPBonus(feral_bonus, apply); - - // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue) - if (getClass() == CLASS_DRUID) - if (int32 feral_bonus = proto->getFeralBonus(ssv->getDPSMod(proto->ScalingStatValue))) - ApplyFeralAPBonus(feral_bonus, apply); } void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingStatValuesEntry const* ssv, bool apply) @@ -8155,14 +8145,16 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt float maxDamage = proto->Damage[0].DamageMax; // If set dpsMod in ScalingStatValue use it for min (70% from average), max (130% from average) damage + int32 extraDPS = 0; if (ssv) { - int32 extraDPS = ssv->getDPSMod(proto->ScalingStatValue); + float damageMultiplier = 0.0f; + extraDPS = ssv->GetDPSAndDamageMultiplier(proto->SubClass, proto->Flags2 & ITEM_FLAGS_EXTRA_CASTER_WEAPON, &damageMultiplier); if (extraDPS) { float average = extraDPS * proto->Delay / 1000.0f; - minDamage = 0.7f * average; - maxDamage = 1.3f * average; + minDamage = (1.0f - damageMultiplier) * average; + maxDamage = (1.0f + damageMultiplier) * average; } } @@ -8194,6 +8186,11 @@ void Player::_ApplyWeaponDamage(uint8 slot, ItemTemplate const* proto, ScalingSt if (CanModifyStats() && (damage || proto->Delay)) UpdateDamagePhysical(attType); + + // Druids get feral AP bonus from weapon dps (lso use DPS from ScalingStatValue) + if (getClass() == CLASS_DRUID) + if (int32 feral_bonus = proto->getFeralBonus(extraDPS)) + ApplyFeralAPBonus(feral_bonus, apply); } void Player::_ApplyWeaponDependentAuraMods(Item* item, WeaponAttackType attackType, bool apply) @@ -24687,7 +24684,7 @@ void Player::SendRefundInfo(Item *item) WorldPacket data(SMSG_ITEM_REFUND_INFO_RESPONSE, 8+4+4+4+4*4+4*4+4+4); data << uint64(item->GetGUID()); // item guid - data << uint32(item->GetPaidMoney()); // money cost + data << uint32(item->GetPaidMoney()); // money cost for (uint8 i = 0; i < MAX_ITEM_EXT_COST_CURRENCIES; ++i) // item cost data { data << uint32(iece->RequiredItem[i]); diff --git a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp index f4e3af72892..53b864b4d90 100755 --- a/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/ItemHandler.cpp @@ -339,7 +339,7 @@ void WorldSession::HandleItemQuerySingleOpcode(WorldPacket & recv_data) data << pProto->ItemStat[i].ItemStatValue; } data << pProto->ScalingStatDistribution; // scaling stats distribution - data << pProto->ScalingStatValue; // some kind of flags used to determine stat values column + data << uint32(0); for (int i = 0; i < MAX_ITEM_PROTO_DAMAGES; ++i) { data << pProto->Damage[i].DamageMin; |
