TrinityCore
Loading...
Searching...
No Matches
Formulas.h
Go to the documentation of this file.
1/*
2 * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#ifndef TRINITY_FORMULAS_H
19#define TRINITY_FORMULAS_H
20
21#include "Creature.h"
22#include "GameTables.h"
23#include "Map.h"
24#include "Player.h"
25#include "ScriptMgr.h"
26#include "SharedDefines.h"
27#include "World.h"
28
29namespace Trinity
30{
32 {
33 if (level < 30)
34 return EXPANSION_CLASSIC;
35 else if (level < 35)
37 else if (level < 40)
39 else if (level < 45)
41 else if (level < 50)
43 else if (level < 60)
45 else if (level < 70)
47 else if (level < 80)
49 else
50 return CURRENT_EXPANSION;
51 }
52
53 namespace Honor
54 {
55 inline float hk_honor_at_level_f(uint8 level, float multiplier = 1.0f)
56 {
57 float honor = multiplier * level * 1.55f;
58 sScriptMgr->OnHonorCalculation(honor, level, multiplier);
59 return honor;
60 }
61
62 inline uint32 hk_honor_at_level(uint8 level, float multiplier = 1.0f)
63 {
64 return uint32(ceil(hk_honor_at_level_f(level, multiplier)));
65 }
66 } // namespace Trinity::Honor
67
68 namespace XP
69 {
70 inline uint8 GetGrayLevel(uint8 pl_level)
71 {
72 uint8 level;
73
74 if (pl_level < 7)
75 level = 0;
76 else if (pl_level < 35)
77 {
78 uint8 count = 0;
79 for (int i = 15; i <= pl_level; ++i)
80 if (i % 5 == 0) ++count;
81
82 level = (pl_level - 7) - (count - 1);
83 }
84 else
85 level = pl_level - 10;
86
87 sScriptMgr->OnGrayLevelCalculation(level, pl_level);
88 return level;
89 }
90
91 inline XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
92 {
93 XPColorChar color;
94
95 if (mob_level >= pl_level + 5)
96 color = XP_RED;
97 else if (mob_level >= pl_level + 3)
98 color = XP_ORANGE;
99 else if (mob_level >= pl_level - 2)
100 color = XP_YELLOW;
101 else if (mob_level > GetGrayLevel(pl_level))
102 color = XP_GREEN;
103 else
104 color = XP_GRAY;
105
106 sScriptMgr->OnColorCodeCalculation(color, pl_level, mob_level);
107 return color;
108 }
109
111 {
112 uint8 diff;
113
114 if (pl_level < 4)
115 diff = 5;
116 else if (pl_level < 10)
117 diff = 6;
118 else if (pl_level < 12)
119 diff = 7;
120 else if (pl_level < 16)
121 diff = 8;
122 else if (pl_level < 20)
123 diff = 9;
124 else if (pl_level < 30)
125 diff = 11;
126 else if (pl_level < 40)
127 diff = 12;
128 else if (pl_level < 45)
129 diff = 13;
130 else if (pl_level < 50)
131 diff = 14;
132 else if (pl_level < 55)
133 diff = 15;
134 else if (pl_level < 60)
135 diff = 16;
136 else
137 diff = 17;
138
139 sScriptMgr->OnZeroDifferenceCalculation(diff, pl_level);
140 return diff;
141 }
142
143 inline uint32 BaseGain(uint8 pl_level, uint8 mob_level)
144 {
145 uint32 baseGain;
146
147 GtXpEntry const* xpPlayer = sXpGameTable.GetRow(pl_level);
148 GtXpEntry const* xpMob = sXpGameTable.GetRow(mob_level);
149
150 if (mob_level >= pl_level)
151 {
152 uint8 nLevelDiff = mob_level - pl_level;
153 if (nLevelDiff > 4)
154 nLevelDiff = 4;
155
156 baseGain = uint32(round(xpPlayer->PerKill * (1 + 0.05f * nLevelDiff)));
157 }
158 else
159 {
160 uint8 gray_level = GetGrayLevel(pl_level);
161 if (mob_level > gray_level)
162 {
163 uint8 ZD = GetZeroDifference(pl_level);
164 baseGain = uint32(round(xpMob->PerKill * ((1 - ((pl_level - mob_level) / float(ZD))) * (xpMob->Divisor / xpPlayer->Divisor))));
165 }
166 else
167 baseGain = 0;
168 }
169
170 if (sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO) && pl_level != mob_level)
171 {
172 // Use mob level instead of player level to avoid overscaling on gain in a min is enforced
173 uint32 baseGainMin = BaseGain(pl_level, pl_level) * sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO) / 100;
174 baseGain = std::max(baseGainMin, baseGain);
175 }
176
177 sScriptMgr->OnBaseGainCalculation(baseGain, pl_level, mob_level);
178 return baseGain;
179 }
180
181 inline uint32 Gain(Player* player, Unit* u, bool isBattleGround = false)
182 {
183 Creature* creature = u->ToCreature();
184 uint32 gain = 0;
185
186 if (!creature || creature->CanGiveExperience())
187 {
188 float xpMod = 1.0f;
189
190 gain = BaseGain(player->GetLevel(), u->GetLevelForTarget(player));
191
192 if (gain && creature)
193 {
194 // Players get only 10% xp for killing creatures of lower expansion levels than himself
196 gain = uint32(round(gain / 10.0f));
197
198 if (creature->IsElite())
199 {
200 // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus.
201 if (u->GetMap()->IsDungeon())
202 xpMod *= 2.75f;
203 else
204 xpMod *= 2.0f;
205 }
206
207 xpMod *= creature->GetCreatureTemplate()->ModExperience;
208 }
209
210 xpMod *= isBattleGround ? sWorld->getRate(RATE_XP_BG_KILL) : sWorld->getRate(RATE_XP_KILL);
211 if (creature && creature->m_PlayerDamageReq) // if players dealt less than 50% of the damage and were credited anyway (due to CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ), scale XP gained appropriately (linear scaling)
212 xpMod *= 1.0f - 2.0f * creature->m_PlayerDamageReq / creature->GetMaxHealth();
213
214 gain = uint32(gain * xpMod);
215 }
216
217 sScriptMgr->OnGainCalculation(gain, player, u);
218 return gain;
219 }
220
221 inline float xp_in_group_rate(uint32 count, bool isRaid)
222 {
223 float rate;
224
225 if (isRaid)
226 {
227 // FIXME: Must apply decrease modifiers depending on raid size.
228 // set to < 1 to, so client will display raid related strings
229 rate = 0.99f;
230 }
231 else
232 {
233 switch (count)
234 {
235 case 0:
236 case 1:
237 case 2:
238 rate = 1.0f;
239 break;
240 case 3:
241 rate = 1.166f;
242 break;
243 case 4:
244 rate = 1.3f;
245 break;
246 case 5:
247 default:
248 rate = 1.4f;
249 }
250 }
251
252 sScriptMgr->OnGroupRateCalculation(rate, count, isRaid);
253 return rate;
254 }
255 } // namespace Trinity::XP
256
257 namespace Currency
258 {
260 {
261 if (rate <= 1500)
262 return 1350; // Default conquest points
263 else if (rate > 3000)
264 rate = 3000;
265
266 // http://www.arenajunkies.com/topic/179536-conquest-point-cap-vs-personal-rating-chart/page__st__60#entry3085246
267 return uint32(1.4326 * ((1511.26 / (1 + 1639.28 / exp(0.00412 * rate))) + 850.15));
268 }
269
271 {
272 // WowWiki: Battleground ratings receive a bonus of 22.2% to the cap they generate
273 return uint32((ConquestRatingCalculator(rate) * 1.222f) + 0.5f);
274 }
275 } // namespace Trinity::Currency
276} // namespace Trinity
277
278#endif
uint8_t uint8
Definition Define.h:156
uint32_t uint32
Definition Define.h:154
GameTable< GtXpEntry > sXpGameTable
#define sScriptMgr
Definition ScriptMgr.h:1449
#define CURRENT_EXPANSION
XPColorChar
@ XP_GREEN
@ XP_GRAY
@ XP_YELLOW
@ XP_RED
@ XP_ORANGE
@ EXPANSION_WARLORDS_OF_DRAENOR
@ EXPANSION_CLASSIC
@ EXPANSION_THE_WAR_WITHIN
@ EXPANSION_MISTS_OF_PANDARIA
@ EXPANSION_DRAGONFLIGHT
@ EXPANSION_CATACLYSM
@ EXPANSION_SHADOWLANDS
@ EXPANSION_BATTLE_FOR_AZEROTH
CreatureDifficulty const * GetCreatureDifficulty() const
Definition Creature.h:268
bool CanGiveExperience() const
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:266
bool IsElite() const
uint64 m_PlayerDamageReq
Definition Creature.h:416
bool IsDungeon() const
Definition Map.cpp:3267
Creature * ToCreature()
Definition Object.h:121
Definition Unit.h:635
uint64 GetMaxHealth() const
Definition Unit.h:789
uint8 GetLevelForTarget(WorldObject const *) const override
Definition Unit.h:759
uint8 GetLevel() const
Definition Unit.h:757
Map * GetMap() const
Definition Object.h:411
#define sWorld
Definition World.h:916
@ CONFIG_MIN_CREATURE_SCALED_XP_RATIO
Definition World.h:282
@ RATE_XP_KILL
Definition World.h:477
@ RATE_XP_BG_KILL
Definition World.h:478
uint32 ConquestRatingCalculator(uint32 rate)
Definition Formulas.h:259
uint32 BgConquestRatingCalculator(uint32 rate)
Definition Formulas.h:270
float hk_honor_at_level_f(uint8 level, float multiplier=1.0f)
Definition Formulas.h:55
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:62
XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
Definition Formulas.h:91
float xp_in_group_rate(uint32 count, bool isRaid)
Definition Formulas.h:221
uint8 GetZeroDifference(uint8 pl_level)
Definition Formulas.h:110
uint8 GetGrayLevel(uint8 pl_level)
Definition Formulas.h:70
uint32 BaseGain(uint8 pl_level, uint8 mob_level)
Definition Formulas.h:143
uint32 GetExpansionForLevel(uint32 level)
Definition Formulas.h:31
int32 GetHealthScalingExpansion() const
float Divisor
Definition GameTables.h:174
float PerKill
Definition GameTables.h:171