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 "DBCStores.h"
22#include "Creature.h"
23#include "Log.h"
24#include "Map.h"
25#include "Player.h"
26#include "ScriptMgr.h"
27#include "SharedDefines.h"
28#include "World.h"
29
30namespace Trinity
31{
32 namespace Honor
33 {
34 inline float hk_honor_at_level_f(uint8 level, float multiplier = 1.0f)
35 {
36 float honor = multiplier * level * 1.55f;
37 sScriptMgr->OnHonorCalculation(honor, level, multiplier);
38 return honor;
39 }
40
41 inline uint32 hk_honor_at_level(uint8 level, float multiplier = 1.0f)
42 {
43 return uint32(ceil(hk_honor_at_level_f(level, multiplier)));
44 }
45 } // namespace Trinity::Honor
46
47 namespace XP
48 {
49 inline uint8 GetGrayLevel(uint8 pl_level)
50 {
51 uint8 level;
52
53 if (pl_level <= 5)
54 level = 0;
55 else if (pl_level <= 39)
56 level = pl_level - 5 - pl_level / 10;
57 else if (pl_level <= 59)
58 level = pl_level - 1 - pl_level / 5;
59 else
60 level = pl_level - 9;
61
62 sScriptMgr->OnGrayLevelCalculation(level, pl_level);
63 return level;
64 }
65
66 inline XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
67 {
68 XPColorChar color;
69
70 if (mob_level >= pl_level + 5)
71 color = XP_RED;
72 else if (mob_level >= pl_level + 3)
73 color = XP_ORANGE;
74 else if (mob_level >= pl_level - 2)
75 color = XP_YELLOW;
76 else if (mob_level > GetGrayLevel(pl_level))
77 color = XP_GREEN;
78 else
79 color = XP_GRAY;
80
81 sScriptMgr->OnColorCodeCalculation(color, pl_level, mob_level);
82 return color;
83 }
84
85 inline uint8 GetZeroDifference(uint8 pl_level)
86 {
87 uint8 diff;
88
89 if (pl_level < 8)
90 diff = 5;
91 else if (pl_level < 10)
92 diff = 6;
93 else if (pl_level < 12)
94 diff = 7;
95 else if (pl_level < 16)
96 diff = 8;
97 else if (pl_level < 20)
98 diff = 9;
99 else if (pl_level < 30)
100 diff = 11;
101 else if (pl_level < 40)
102 diff = 12;
103 else if (pl_level < 45)
104 diff = 13;
105 else if (pl_level < 50)
106 diff = 14;
107 else if (pl_level < 55)
108 diff = 15;
109 else if (pl_level < 60)
110 diff = 16;
111 else
112 diff = 17;
113
114 sScriptMgr->OnZeroDifferenceCalculation(diff, pl_level);
115 return diff;
116 }
117
118 inline uint32 BaseGain(uint8 pl_level, uint8 mob_level, ContentLevels content)
119 {
120 uint32 baseGain;
121 uint32 nBaseExp;
122
123 switch (content)
124 {
125 case CONTENT_1_60:
126 nBaseExp = 45;
127 break;
128 case CONTENT_61_70:
129 nBaseExp = 235;
130 break;
131 case CONTENT_71_80:
132 nBaseExp = 580;
133 break;
134 default:
135 TC_LOG_ERROR("misc", "BaseGain: Unsupported content level {}", content);
136 nBaseExp = 45;
137 break;
138 }
139
140 if (mob_level >= pl_level)
141 {
142 uint8 nLevelDiff = mob_level - pl_level;
143 if (nLevelDiff > 4)
144 nLevelDiff = 4;
145
146 baseGain = ((pl_level * 5 + nBaseExp) * (20 + nLevelDiff) / 10 + 1) / 2;
147 }
148 else
149 {
150 uint8 gray_level = GetGrayLevel(pl_level);
151 if (mob_level > gray_level)
152 {
153 uint8 ZD = GetZeroDifference(pl_level);
154 baseGain = (pl_level * 5 + nBaseExp) * (ZD + mob_level - pl_level) / ZD;
155 }
156 else
157 baseGain = 0;
158 }
159
161 {
162 // Use mob level instead of player level to avoid overscaling on gain in a min is enforced
163 uint32 baseGainMin = (mob_level * 5 + nBaseExp) * sWorld->getIntConfig(CONFIG_MIN_CREATURE_SCALED_XP_RATIO) / 100;
164 baseGain = std::max(baseGainMin, baseGain);
165 }
166
167 sScriptMgr->OnBaseGainCalculation(baseGain, pl_level, mob_level, content);
168 return baseGain;
169 }
170
171 inline uint32 Gain(Player* player, Unit* u, bool isBattleGround = false)
172 {
173 Creature* creature = u->ToCreature();
174 uint32 gain = 0;
175
176 if (!creature || creature->CanGiveExperience())
177 {
178 float xpMod = 1.0f;
179
180 gain = BaseGain(player->GetLevel(), u->GetLevel(), GetContentLevelsForMapAndZone(u->GetMapId(), u->GetZoneId()));
181
182 if (gain && creature)
183 {
184 if (creature->isElite())
185 {
186 // Elites in instances have a 2.75x XP bonus instead of the regular 2x world bonus.
187 if (u->GetMap()->IsDungeon())
188 xpMod *= 2.75f;
189 else
190 xpMod *= 2.0f;
191 }
192
193 xpMod *= creature->GetCreatureTemplate()->ModExperience;
194 }
195
196 xpMod *= isBattleGround ? sWorld->getRate(RATE_XP_BG_KILL) : sWorld->getRate(RATE_XP_KILL);
197 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)
198 xpMod *= 1.0f - 2.0f * creature->m_PlayerDamageReq / creature->GetMaxHealth();
199
200 gain = uint32(gain * xpMod);
201 }
202
203 sScriptMgr->OnGainCalculation(gain, player, u);
204 return gain;
205 }
206
207 inline float xp_in_group_rate(uint32 count, bool isRaid)
208 {
209 float rate;
210
211 if (isRaid)
212 {
213 // FIXME: Must apply decrease modifiers depending on raid size.
214 rate = 1.0f;
215 }
216 else
217 {
218 switch (count)
219 {
220 case 0:
221 case 1:
222 case 2:
223 rate = 1.0f;
224 break;
225 case 3:
226 rate = 1.166f;
227 break;
228 case 4:
229 rate = 1.3f;
230 break;
231 case 5:
232 default:
233 rate = 1.4f;
234 }
235 }
236
237 sScriptMgr->OnGroupRateCalculation(rate, count, isRaid);
238 return rate;
239 }
240 } // namespace Trinity::XP
241} // namespace Trinity
242
243#endif
ContentLevels GetContentLevelsForMapAndZone(uint32 mapid, uint32 zoneId)
ContentLevels
Definition DBCStores.h:51
@ CONTENT_61_70
Definition DBCStores.h:53
@ CONTENT_71_80
Definition DBCStores.h:54
@ CONTENT_1_60
Definition DBCStores.h:52
uint8_t uint8
Definition Define.h:135
uint32_t uint32
Definition Define.h:133
#define TC_LOG_ERROR(filterType__,...)
Definition Log.h:165
#define sScriptMgr
Definition ScriptMgr.h:1168
XPColorChar
@ XP_GREEN
@ XP_GRAY
@ XP_YELLOW
@ XP_RED
@ XP_ORANGE
bool CanGiveExperience() const
uint32 m_PlayerDamageReq
Definition Creature.h:324
CreatureTemplate const * GetCreatureTemplate() const
Definition Creature.h:186
bool isElite() const
bool IsDungeon() const
Definition Map.cpp:4236
static Creature * ToCreature(Object *o)
Definition Object.h:186
Definition Unit.h:769
uint32 GetMaxHealth() const
Definition Unit.h:914
uint8 GetLevel() const
Definition Unit.h:889
uint32 GetMapId() const
Definition Position.h:193
Map * GetMap() const
Definition Object.h:449
uint32 GetZoneId() const
Definition Object.h:373
#define sWorld
Definition World.h:900
@ CONFIG_MIN_CREATURE_SCALED_XP_RATIO
Definition World.h:255
@ RATE_XP_KILL
Definition World.h:429
@ RATE_XP_BG_KILL
Definition World.h:430
float hk_honor_at_level_f(uint8 level, float multiplier=1.0f)
Definition Formulas.h:34
uint32 hk_honor_at_level(uint8 level, float multiplier=1.0f)
Definition Formulas.h:41
XPColorChar GetColorCode(uint8 pl_level, uint8 mob_level)
Definition Formulas.h:66
uint32 Gain(Player *player, Unit *u, bool isBattleGround=false)
Definition Formulas.h:171
uint32 BaseGain(uint8 pl_level, uint8 mob_level, ContentLevels content)
Definition Formulas.h:118
float xp_in_group_rate(uint32 count, bool isRaid)
Definition Formulas.h:207
uint8 GetZeroDifference(uint8 pl_level)
Definition Formulas.h:85
uint8 GetGrayLevel(uint8 pl_level)
Definition Formulas.h:49