diff options
author | Shauren <shauren.trinity@gmail.com> | 2021-02-07 19:19:06 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-02-07 19:19:06 +0100 |
commit | cb47605235a49bb2c6065b2e6de69b657a9c905f (patch) | |
tree | 0bfd95f29afdcd4b1f490ee4cf96f3d7c5a319b1 | |
parent | 5a7560e57c37fbda511b492ea7d7c47f8e68123f (diff) |
Core/Players: Implemented secondary stat diminishing
-rw-r--r-- | sql/updates/hotfixes/master/2021_02_07_00_hotfixes.sql | 11 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.cpp | 4 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/HotfixDatabase.h | 3 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2LoadInfo.h | 15 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.cpp | 15 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Stores.h | 3 | ||||
-rw-r--r-- | src/server/game/DataStores/DB2Structure.h | 7 | ||||
-rw-r--r-- | src/server/game/DataStores/DBCEnums.h | 20 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 59 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 1 |
10 files changed, 132 insertions, 6 deletions
diff --git a/sql/updates/hotfixes/master/2021_02_07_00_hotfixes.sql b/sql/updates/hotfixes/master/2021_02_07_00_hotfixes.sql new file mode 100644 index 00000000000..063dc163473 --- /dev/null +++ b/sql/updates/hotfixes/master/2021_02_07_00_hotfixes.sql @@ -0,0 +1,11 @@ +-- +-- Table structure for table `global_curve` +-- +DROP TABLE IF EXISTS `global_curve`; +CREATE TABLE `global_curve` ( + `ID` int(10) unsigned NOT NULL DEFAULT '0', + `CurveID` int(11) NOT NULL DEFAULT '0', + `Type` int(11) NOT NULL DEFAULT '0', + `VerifiedBuild` int(11) NOT NULL DEFAULT '0', + PRIMARY KEY (`ID`,`VerifiedBuild`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; diff --git a/src/server/database/Database/Implementation/HotfixDatabase.cpp b/src/server/database/Database/Implementation/HotfixDatabase.cpp index e181cef4a6b..33102e07235 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.cpp +++ b/src/server/database/Database/Implementation/HotfixDatabase.cpp @@ -621,6 +621,10 @@ void HotfixDatabaseConnection::DoPrepareStatements() PrepareStatement(HOTFIX_SEL_GEM_PROPERTIES, "SELECT ID, EnchantId, Type FROM gem_properties WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); PREPARE_MAX_ID_STMT(HOTFIX_SEL_GEM_PROPERTIES, "SELECT MAX(ID) + 1 FROM gem_properties", CONNECTION_SYNCH); + // GlobalCurve.db2 + PrepareStatement(HOTFIX_SEL_GLOBAL_CURVE, "SELECT ID, CurveID, Type FROM global_curve WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); + PREPARE_MAX_ID_STMT(HOTFIX_SEL_GLOBAL_CURVE, "SELECT MAX(ID) + 1 FROM global_curve", CONNECTION_SYNCH); + // GlyphBindableSpell.db2 PrepareStatement(HOTFIX_SEL_GLYPH_BINDABLE_SPELL, "SELECT ID, SpellID, GlyphPropertiesID FROM glyph_bindable_spell WHERE (`VerifiedBuild` > 0) = ?", CONNECTION_SYNCH); PREPARE_MAX_ID_STMT(HOTFIX_SEL_GLYPH_BINDABLE_SPELL, "SELECT MAX(ID) + 1 FROM glyph_bindable_spell", CONNECTION_SYNCH); diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index d1b18a3ec5f..4990680e6c9 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -359,6 +359,9 @@ enum HotfixDatabaseStatements : uint32 HOTFIX_SEL_GEM_PROPERTIES, HOTFIX_SEL_GEM_PROPERTIES_MAX_ID, + HOTFIX_SEL_GLOBAL_CURVE, + HOTFIX_SEL_GLOBAL_CURVE_MAX_ID, + HOTFIX_SEL_GLYPH_BINDABLE_SPELL, HOTFIX_SEL_GLYPH_BINDABLE_SPELL_MAX_ID, diff --git a/src/server/game/DataStores/DB2LoadInfo.h b/src/server/game/DataStores/DB2LoadInfo.h index 4316faff9f4..7af372f4fac 100644 --- a/src/server/game/DataStores/DB2LoadInfo.h +++ b/src/server/game/DataStores/DB2LoadInfo.h @@ -2226,6 +2226,21 @@ struct GemPropertiesLoadInfo } }; +struct GlobalCurveLoadInfo +{ + static DB2LoadInfo const* Instance() + { + static DB2FieldMeta const fields[] = + { + { false, FT_INT, "ID" }, + { true, FT_INT, "CurveID" }, + { true, FT_INT, "Type" }, + }; + static DB2LoadInfo const loadInfo(&fields[0], std::extent<decltype(fields)>::value, GlobalCurveMeta::Instance(), HOTFIX_SEL_GLOBAL_CURVE); + return &loadInfo; + } +}; + struct GlyphBindableSpellLoadInfo { static DB2LoadInfo const* Instance() diff --git a/src/server/game/DataStores/DB2Stores.cpp b/src/server/game/DataStores/DB2Stores.cpp index 026ec817e1e..0edc7be8cce 100644 --- a/src/server/game/DataStores/DB2Stores.cpp +++ b/src/server/game/DataStores/DB2Stores.cpp @@ -140,6 +140,7 @@ DB2Storage<GarrPlotInstanceEntry> sGarrPlotInstanceStore("GarrPlot DB2Storage<GarrSiteLevelEntry> sGarrSiteLevelStore("GarrSiteLevel.db2", GarrSiteLevelLoadInfo::Instance()); DB2Storage<GarrSiteLevelPlotInstEntry> sGarrSiteLevelPlotInstStore("GarrSiteLevelPlotInst.db2", GarrSiteLevelPlotInstLoadInfo::Instance()); DB2Storage<GemPropertiesEntry> sGemPropertiesStore("GemProperties.db2", GemPropertiesLoadInfo::Instance()); +DB2Storage<GlobalCurveEntry> sGlobalCurveStore("GlobalCurve.db2", GlobalCurveLoadInfo::Instance()); DB2Storage<GlyphBindableSpellEntry> sGlyphBindableSpellStore("GlyphBindableSpell.db2", GlyphBindableSpellLoadInfo::Instance()); DB2Storage<GlyphPropertiesEntry> sGlyphPropertiesStore("GlyphProperties.db2", GlyphPropertiesLoadInfo::Instance()); DB2Storage<GlyphRequiredSpecEntry> sGlyphRequiredSpecStore("GlyphRequiredSpec.db2", GlyphRequiredSpecLoadInfo::Instance()); @@ -671,6 +672,7 @@ uint32 DB2Manager::LoadStores(std::string const& dataPath, LocaleConstant defaul LOAD_DB2(sGarrSiteLevelStore); LOAD_DB2(sGarrSiteLevelPlotInstStore); LOAD_DB2(sGemPropertiesStore); + LOAD_DB2(sGlobalCurveStore); LOAD_DB2(sGlyphBindableSpellStore); LOAD_DB2(sGlyphPropertiesStore); LOAD_DB2(sGlyphRequiredSpecStore); @@ -2191,9 +2193,13 @@ std::vector<uint32> const* DB2Manager::GetFactionTeamList(uint32 faction) const return Trinity::Containers::MapGetValuePtr(_factionTeams, faction); } -HeirloomEntry const* DB2Manager::GetHeirloomByItemId(uint32 itemId) const +uint32 DB2Manager::GetGlobalCurveId(GlobalCurve globalCurveType) const { - return Trinity::Containers::MapGetValuePtr(_heirlooms, itemId); + for (GlobalCurveEntry const* globalCurveEntry : sGlobalCurveStore) + if (GlobalCurve(globalCurveEntry->Type) == globalCurveType) + return globalCurveEntry->CurveID; + + return 0; } std::vector<uint32> const* DB2Manager::GetGlyphBindableSpells(uint32 glyphPropertiesId) const @@ -2206,6 +2212,11 @@ std::vector<uint32> const* DB2Manager::GetGlyphRequiredSpecs(uint32 glyphPropert return Trinity::Containers::MapGetValuePtr(_glyphRequiredSpecs, glyphPropertiesId); } +HeirloomEntry const* DB2Manager::GetHeirloomByItemId(uint32 itemId) const +{ + return Trinity::Containers::MapGetValuePtr(_heirlooms, itemId); +} + DB2Manager::ItemBonusList const* DB2Manager::GetItemBonusList(uint32 bonusListId) const { return Trinity::Containers::MapGetValuePtr(_itemBonusLists, bonusListId); diff --git a/src/server/game/DataStores/DB2Stores.h b/src/server/game/DataStores/DB2Stores.h index 0cb82d7ff70..4d4aa2594ac 100644 --- a/src/server/game/DataStores/DB2Stores.h +++ b/src/server/game/DataStores/DB2Stores.h @@ -343,9 +343,10 @@ public: EmotesTextSoundEntry const* GetTextSoundEmoteFor(uint32 emote, uint8 race, uint8 gender, uint8 class_) const; float EvaluateExpectedStat(ExpectedStatType stat, uint32 level, int32 expansion, uint32 contentTuningId, Classes unitClass) const; std::vector<uint32> const* GetFactionTeamList(uint32 faction) const; - HeirloomEntry const* GetHeirloomByItemId(uint32 itemId) const; + uint32 GetGlobalCurveId(GlobalCurve globalCurveType) const; std::vector<uint32> const* GetGlyphBindableSpells(uint32 glyphPropertiesId) const; std::vector<uint32> const* GetGlyphRequiredSpecs(uint32 glyphPropertiesId) const; + HeirloomEntry const* GetHeirloomByItemId(uint32 itemId) const; ItemBonusList const* GetItemBonusList(uint32 bonusListId) const; uint32 GetItemBonusListForItemLevelDelta(int16 delta) const; std::set<uint32> GetDefaultItemBonusTree(uint32 itemId, ItemContext itemContext) const; diff --git a/src/server/game/DataStores/DB2Structure.h b/src/server/game/DataStores/DB2Structure.h index e2e34fc2415..282f401f4c8 100644 --- a/src/server/game/DataStores/DB2Structure.h +++ b/src/server/game/DataStores/DB2Structure.h @@ -1530,6 +1530,13 @@ struct GemPropertiesEntry int32 Type; }; +struct GlobalCurveEntry +{ + uint32 ID; + int32 CurveID; + int32 Type; +}; + struct GlyphBindableSpellEntry { uint32 ID; diff --git a/src/server/game/DataStores/DBCEnums.h b/src/server/game/DataStores/DBCEnums.h index e5232b14ce9..451269a540c 100644 --- a/src/server/game/DataStores/DBCEnums.h +++ b/src/server/game/DataStores/DBCEnums.h @@ -976,6 +976,26 @@ enum FactionMasks // if none flags set then non-aggressive creature }; +enum class GlobalCurve : int32 +{ + CritDiminishing = 0, + MasteryDiminishing = 1, + HasteDiminishing = 2, + SpeedDiminishing = 3, + AvoidanceDiminishing = 4, + VersatilityDoneDiminishing = 5, + LifestealDiminishing = 6, + DodgeDiminishing = 7, + BlockDiminishing = 8, + ParryDiminishing = 9, + + VersatilityTakenDiminishing = 11, + + ContentTuningPvpItemLevelHealthScaling = 13, + ContentTuningPvpLevelDamageScaling = 14, + ContentTuningPvpItemLevelDamageScaling = 15, +}; + #define MAX_ITEM_PROTO_FLAGS 4 #define MAX_ITEM_PROTO_ZONES 2 #define MAX_ITEM_PROTO_SOCKETS 3 diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 2284bb75eea..07ea9207ede 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -5128,12 +5128,65 @@ float Player::GetRatingMultiplier(CombatRating cr) const float Player::GetRatingBonusValue(CombatRating cr) const { - float baseResult = float(m_activePlayerData->CombatRatings[cr]) * GetRatingMultiplier(cr); + float baseResult = ApplyRatingDiminishing(cr, float(m_activePlayerData->CombatRatings[cr]) * GetRatingMultiplier(cr)); if (cr != CR_RESILIENCE_PLAYER_DAMAGE) return baseResult; return float(1.0f - pow(0.99f, baseResult)) * 100.0f; } +float Player::ApplyRatingDiminishing(CombatRating cr, float bonusValue) const +{ + uint32 diminishingCurveId = 0; + switch (cr) + { + case CR_DODGE: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::DodgeDiminishing); + break; + case CR_PARRY: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::ParryDiminishing); + break; + case CR_BLOCK: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::BlockDiminishing); + break; + case CR_CRIT_MELEE: + case CR_CRIT_RANGED: + case CR_CRIT_SPELL: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::CritDiminishing); + break; + case CR_SPEED: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::SpeedDiminishing); + break; + case CR_LIFESTEAL: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::LifestealDiminishing); + break; + case CR_HASTE_MELEE: + case CR_HASTE_RANGED: + case CR_HASTE_SPELL: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::HasteDiminishing); + break; + case CR_AVOIDANCE: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::AvoidanceDiminishing); + break; + case CR_MASTERY: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::MasteryDiminishing); + break; + case CR_VERSATILITY_DAMAGE_DONE: + case CR_VERSATILITY_HEALING_DONE: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::VersatilityDoneDiminishing); + break; + case CR_VERSATILITY_DAMAGE_TAKEN: + diminishingCurveId = sDB2Manager.GetGlobalCurveId(GlobalCurve::VersatilityTakenDiminishing); + break; + default: + break; + } + + if (diminishingCurveId) + return sDB2Manager.GetCurveValueAt(diminishingCurveId, bonusValue); + + return bonusValue; +} + float Player::GetExpertiseDodgeOrParryReduction(WeaponAttackType attType) const { float baseExpertise = 7.5f; @@ -5224,8 +5277,8 @@ void Player::UpdateRating(CombatRating cr) { // explicit affected values float const multiplier = GetRatingMultiplier(cr); - float const oldVal = oldRating * multiplier; - float const newVal = amount * multiplier; + float const oldVal = ApplyRatingDiminishing(cr, oldRating * multiplier); + float const newVal = ApplyRatingDiminishing(cr, amount * multiplier); switch (cr) { case CR_HASTE_MELEE: diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 17beaaeec1c..8e8e5a7a13c 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -1823,6 +1823,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> void GetDodgeFromAgility(float &diminishing, float &nondiminishing) const; float GetRatingMultiplier(CombatRating cr) const; float GetRatingBonusValue(CombatRating cr) const; + float ApplyRatingDiminishing(CombatRating cr, float bonusValue) const; /// Returns base spellpower bonus from spellpower stat on items, without spellpower from intellect stat uint32 GetBaseSpellPowerBonus() const { return m_baseSpellPower; } |