TrinityCore
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 < 60)
34 return EXPANSION_CLASSIC;
35 else if (level < 70)
37 else if (level < 80)
39 else if (level < 85)
41 else if (level < 90)
43 else if (level < 100)
45 else
46 return CURRENT_EXPANSION;
47 }
48
49 namespace Honor
50 {
51 inline float hk_honor_at_level_f(uint8 level, float multiplier = 1.0f)
52 {
53 float honor = multiplier * level * 1.55f;
54 sScriptMgr->OnHonorCalculation(honor, level, multiplier);
55 return honor;
56 }
57
58 inline uint32 hk_honor_at_level(uint8 level, float multiplier = 1.0f)
59 {
60 return uint32(ceil(hk_honor_at_level_f(level, multiplier)));
61 }
62 } // namespace Trinity::Honor
63
64 namespace XP
65 {
66 inline uint8 GetGrayLevel(uint8 pl_level)
67 {
68 uint8 level;
69
70 if (pl_level < 7)
71 level = 0;
72 else if (pl_level < 35)
73 {
74 uint8 count = 0;
75 for (int i = 15; i <= pl_level; ++i)
76 if (i % 5 == 0) ++count;
77
78 level = (pl_level - 7) - (count - 1);
79 }
80 else
81 level = pl_level - 10;
82
83 sScriptMgr->OnGrayLevelCalculation(level, pl_level);
84 return level;
85 }
86
87 inline XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
88 {
89 XPColorChar color;
90
91 if (mob_level >= pl_level + 5)
92 color = XP_RED;
93 else if (mob_level >= pl_level + 3)
94 color = XP_ORANGE;
95 else if (mob_level >= pl_level - 2)
96 color = XP_YELLOW;
97 else if (mob_level > GetGrayLevel(pl_level))
98 color = XP_GREEN;
99 else
100 color = XP_GRAY;
101
102 sScriptMgr->OnColorCodeCalculation(color, pl_level, mob_level);
103 return color;
104 }
105
107 {
108 uint8 diff;
109
110 if (pl_level < 4)
111 diff = 5;
112 else if (pl_level < 10)
113 diff = 6;
114 else if (pl_level < 12)
115 diff = 7;
116 else if (pl_level < 16)
117 diff = 8;
118 else if (pl_level < 20)
119 diff = 9;
120 else if (pl_level < 30)
121 diff = 11;
122 else if (pl_level < 40)
123 diff = 12;
124 else if (pl_level < 45)
125 diff = 13;
126 else if (pl_level < 50)
127 diff = 14;
128 else if (pl_level < 55)
129 diff = 15;
130 else if (pl_level < 60)
131 diff = 16;
132 else
133 diff = 17;
134
135 sScriptMgr->OnZeroDifferenceCalculation(diff, pl_level);
136 return diff;
137 }
138
139 inline uint32 BaseGain(uint8 pl_level, uint8 mob_level)
140 {
141 uint32 baseGain;
142
143 GtXpEntry const* xpPlayer = sXpGameTable.GetRow(pl_level);
144 GtXpEntry const* xpMob = sXpGameTable.GetRow(mob_level);
145
146 if (mob_level >= pl_level)
147 {
148 uint8 nLevelDiff = mob_level - pl_level;
149 if (nLevelDiff > 4)
150 nLevelDiff = 4;
151
152 baseGain = uint32(round(xpPlayer->PerKill * (1 + 0.05f * nLevelDiff)));
153 }
154 else
155 {
156 uint8 gray_level = GetGrayLevel(pl_level);
157 if (mob_level > gray_level)
158 {
159 uint8 ZD = GetZeroDifference(pl_level);
160 baseGain = uint32(round(xpMob->PerKill * ((1 - ((pl_level - mob_level) / float(ZD))) * (xpMob->Divisor / xpPlayer->Divisor))));
161 }
162 else
163 baseGain = 0;
164 }
165
166 if (sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO) && pl_level != mob_level)
167 {
168 // Use mob level instead of player level to avoid overscaling on gain in a min is enforced
169 uint32 baseGainMin = BaseGain(pl_level, pl_level) * sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO) / 100;
170 baseGain = std::max(baseGainMin, baseGain);
171 }
172
173 sScriptMgr->OnBaseGainCalculation(baseGain, pl_level, mob_level);
174 return baseGain;
175 }
176
177 inline uint32 Gain(Player* player, Unit* u, bool isBattleGround = false)
178 {
179 Creature* creature = u->ToCreature();
180 uint32 gain = 0;
181
182 if (!creature || creature->CanGiveExperience())
183 {
184 float xpMod = 1.0f;
185
186 gain = BaseGain(player->GetLevel(), u->GetLevelForTarget(player));
187
188 if (gain && creature)
189 {
190 // Players get only 10% xp for killing creatures of lower expansion levels than himself
192 gain = uint32(round(gain / 10.0f));
193
194 if (creature->IsElite())
195 {
196 // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus.
197 if (u->GetMap()->IsDungeon())
198 xpMod *= 2.75f;
199 else
200 xpMod *= 2.0f;
201 }
202
203 xpMod *= creature->GetCreatureTemplate()->ModExperience;
204 }
205
206 xpMod *= isBattleGround ? sWorld->getRate(RATE_XP_BG_KILL) : sWorld->getRate(RATE_XP_KILL);
207 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)
208 xpMod *= 1.0f - 2.0f * creature->m_PlayerDamageReq / creature->GetMaxHealth();
209
210 gain = uint32(gain * xpMod);
211 }
212
213 sScriptMgr->OnGainCalculation(gain, player, u);
214 return gain;
215 }
216
217 inline float xp_in_group_rate(uint32 count, bool isRaid)
218 {
219 float rate;
220
221 if (isRaid)
222 {
223 // FIXME: Must apply decrease modifiers depending on raid size.
224 // set to < 1 to, so client will display raid related strings
225 rate = 0.99f;
226 }
227 else
228 {
229 switch (count)
230 {
231 case 0:
232 case 1:
233 case 2:
234 rate = 1.0f;
235 break;
236 case 3:
237 rate = 1.166f;
238 break;
239 case 4:
240 rate = 1.3f;
241 break;
242 case 5:
243 default:
244 rate = 1.4f;
245 }
246 }
247
248 sScriptMgr->OnGroupRateCalculation(rate, count, isRaid);
249 return rate;
250 }
251 } // namespace Trinity::XP
252
253 namespace Currency
254 {
256 {
257 if (rate <= 1500)
258 return 1350; // Default conquest points
259 else if (rate > 3000)
260 rate = 3000;
261
262 // http://www.arenajunkies.com/topic/179536-conquest-point-cap-vs-personal-rating-chart/page__st__60#entry3085246
263 return uint32(1.4326 * ((1511.26 / (1 + 1639.28 / exp(0.00412 * rate))) + 850.15));
264 }
265
267 {
268 // WowWiki: Battleground ratings receive a bonus of 22.2% to the cap they generate
269 return uint32((ConquestRatingCalculator(rate) * 1.222f) + 0.5f);
270 }
271 } // namespace Trinity::Currency
272} // namespace Trinity
273
274#endif
uint8_t uint8
Definition: Define.h:144
uint32_t uint32
Definition: Define.h:142
GameTable< GtXpEntry > sXpGameTable
Definition: GameTables.cpp:40
#define sScriptMgr
Definition: ScriptMgr.h:1418
#define CURRENT_EXPANSION
XPColorChar
@ XP_GREEN
@ XP_GRAY
@ XP_YELLOW
@ XP_RED
@ XP_ORANGE
@ EXPANSION_WARLORDS_OF_DRAENOR
Definition: SharedDefines.h:95
@ EXPANSION_CLASSIC
Definition: SharedDefines.h:90
@ EXPANSION_THE_BURNING_CRUSADE
Definition: SharedDefines.h:91
@ EXPANSION_MISTS_OF_PANDARIA
Definition: SharedDefines.h:94
@ EXPANSION_CATACLYSM
Definition: SharedDefines.h:93
@ EXPANSION_WRATH_OF_THE_LICH_KING
Definition: SharedDefines.h:92
CreatureDifficulty const * GetCreatureDifficulty() const
Definition: Creature.h:252
bool CanGiveExperience() const
Definition: Creature.cpp:3596
CreatureTemplate const * GetCreatureTemplate() const
Definition: Creature.h:250
bool IsElite() const
Definition: Creature.cpp:2476
uint64 m_PlayerDamageReq
Definition: Creature.h:401
bool IsDungeon() const
Definition: Map.cpp:3238
static Creature * ToCreature(Object *o)
Definition: Object.h:219
Definition: Unit.h:627
uint64 GetMaxHealth() const
Definition: Unit.h:777
uint8 GetLevelForTarget(WorldObject const *) const override
Definition: Unit.h:747
uint8 GetLevel() const
Definition: Unit.h:746
Map * GetMap() const
Definition: Object.h:624
#define sWorld
Definition: World.h:931
@ CONFIG_MIN_CREATURE_SCALED_XP_RATIO
Definition: World.h:284
@ RATE_XP_KILL
Definition: World.h:483
@ RATE_XP_BG_KILL
Definition: World.h:484
uint32 ConquestRatingCalculator(uint32 rate)
Definition: Formulas.h:255
uint32 BgConquestRatingCalculator(uint32 rate)
Definition: Formulas.h:266
float hk_honor_at_level_f(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:51
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition: Formulas.h:58
XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
Definition: Formulas.h:87
uint32 Gain(Player *player, Unit *u, bool isBattleGround=false)
Definition: Formulas.h:177
float xp_in_group_rate(uint32 count, bool isRaid)
Definition: Formulas.h:217
uint8 GetZeroDifference(uint8 pl_level)
Definition: Formulas.h:106
uint8 GetGrayLevel(uint8 pl_level)
Definition: Formulas.h:66
uint32 BaseGain(uint8 pl_level, uint8 mob_level)
Definition: Formulas.h:139
uint32 GetExpansionForLevel(uint32 level)
Definition: Formulas.h:31
int32 GetHealthScalingExpansion() const
Definition: CreatureData.h:459
float Divisor
Definition: GameTables.h:167
float PerKill
Definition: GameTables.h:164