1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! This module provides utility fuctions to work with Hypixel's network level and network experience.
//!
//!
//! This module follows the java implementation of the Hypixel API.\
//! See [here](https://github.com/HypixelDev/PublicAPI/blob/master/hypixel-api-core/src/main/java/net/hypixel/api/util/ILeveling.java).
//!
//! From the formulas written in this implementation, it can be seen
//! that the relation between the network level and the network experience can be expressed as:
//! ```math
//! \frac{dy}{dx} = gx + b \;\;\;\;\; \text{and} \;\;\;\;\; y(1) = 0
//! ```
//! where:
//! - y = network xp
//! - x = network lvl
//! - g = [`GROWTH`]
//! - b = [`BASE`]
//!
//! More specific: the integer part of the network level corresponds to an amount of experience
//! that follows these equations. The fractional part of a network level corresponds to an amount of
//! experience that is is linearly interpolated between two experience amounts corresponding to nearest surrounding
//! integer network levels.
pub const BASE: f64 = 10000.0;
pub const GROWTH: f64 = 2500.0;
const HALF_GROWTH: f64 = GROWTH * 0.5;
const REVERSE_PQ_PREFIX: f64 = - / GROWTH;
const REVERSE_CONST: f64 = REVERSE_PQ_PREFIX * REVERSE_PQ_PREFIX;
const GROWTH_DIVIDES_2: f64 = 2.0 / GROWTH;
/// This function returns the level of a player calculated by the
/// current experience gathered. Unlike [`exact_level`], this function returns
/// the largest integer smaller than the exact level (= floored).
///
/// The result cannot be smaller than `1.0` and negative experience results in `1.0`.
///
/// # Examples
/// ```ignore
/// 0 XP -> 1.0
/// 5000 XP -> 1.0
/// 10000 XP -> 2.0
/// 50000 XP -> 4.0
/// 79342431 XP -> 249.0
/// ```
/// This function returns the exact level of a player calculated by the
/// current experience gathered. Unlike [`calculate_level`], this function does
/// not floor its result and will return an accurate level.
///
/// The result cannot be smaller than `1.0` and negative experience results in `1.0`.
///
/// # Examples
/// ```ignore
/// 0 XP -> 1.0
/// 5000 XP -> 1.5
/// 10000 XP -> 2.0
/// 50000 XP -> 4.71...
/// 79342431 XP -> 249.46...
/// ```
/// This function returns the amount of experience that is needed to progress from `level` to `level + 1`. (e.g. 5 to 6)
/// The levels passed *must* be absolute levels with the smallest level being 1.
/// Smaller values always return the `BASE` constant. The calculation is precise and
/// if a decimal is passed, it returns the XP from the progress of this level to the next
/// level with the same progress. (e.g. 5.5 to 6.5)
///
/// # Examples
/// ```ignore
/// 1 (to 2) = 10000.0 XP
/// 2 (to 3) = 12500.0 XP
/// 3 (to 4) = 15000.0 XP
/// 5 (to 6) = 20000.0 XP
/// 5.5 (to 6.5) = 21250.0 XP
/// 130 (to 131) = 332500.0 XP
/// 250 (to 251) = 632500.0 XP
/// ```
/// This method returns the experience required to reach that level. This method is precise, that means
/// you can pass any progress of a level to receive the experience to reach that progress. (e.g. 5.764 returns
/// the experience required to reach level 5 and 76.4% of the experience required to go from level 5 to level 6).
///
/// # Examples
/// ```ignore
/// 1.0 = 0.0 XP
/// 2.0 = 10000.0 XP
/// 3.0 = 22500.0 XP
/// 5.0 = 55000.0 XP
/// 5.764 = 70280.0 XP
/// 130.0 = 21930000.0 XP
/// 250.43 = 79951975.0 XP
/// ```
/// Helper method that may only be called by full levels (meaning no fractional part)
/// and has the same functionality as [`total_xp_to_level`] but doesn't support progress
/// and will return wrong values due to following a parabola instead of a line in between integer levels.
/// This method returns the current progress of this level to reach the next level. This method is as
/// precise as possible due to rounding errors on the mantissa. The first 10 decimals are totally
/// accurate.
///
/// # Examples
/// ```ìgnore
/// 5000.0 XP (Lv. 1) = 0.5 (50 %)
/// 22499.0 XP (Lv. 2) = 0.99992 (99.992 %)
/// 5324224.0 XP (Lv. 62) = 0.856763076923077 (85.6763076923077 %)
/// 23422443.0 XP (Lv. 134) = 0.4304905109489051 (43.04905109489051 %)
/// ```