-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Mana decay computation #1334
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -41,14 +41,88 @@ impl ManaStructure { | |||||||||||||
} | ||||||||||||||
|
||||||||||||||
/// Returns the mana decay factor for the given epoch index. | ||||||||||||||
pub fn decay_factor_at(&self, epoch_index: EpochIndex) -> Option<u32> { | ||||||||||||||
self.decay_factors.get(*epoch_index as usize).copied() | ||||||||||||||
pub fn decay_factor_at(&self, epoch_index: impl Into<EpochIndex>) -> Option<u32> { | ||||||||||||||
self.decay_factors.get(*epoch_index.into() as usize).copied() | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/// Returns the max mana that can exist with the mana bits defined. | ||||||||||||||
pub fn max_mana(&self) -> u64 { | ||||||||||||||
(1 << self.bits_count) - 1 | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
pub fn decay(&self, value: u64, n: u64) -> u64 { | ||||||||||||||
/// Returns the upper n bits of a u64 value. | ||||||||||||||
fn upper_bits(v: u64, n: usize) -> u64 { | ||||||||||||||
v >> n | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/// Returns the lower n bits of a u64 value. | ||||||||||||||
fn lower_bits(mut v: u64, n: usize) -> u64 { | ||||||||||||||
v = v << (64 - n); | ||||||||||||||
v >> (64 - n) | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
/// Returns the result of the multiplication ((value_hi << 32 + value_lo) * mult_factor) >> shift_factor | ||||||||||||||
/// (where mult_factor is a uint32, value_hi and value_lo are uint64 smaller than 2^32, and 0 <= shift_factor <= | ||||||||||||||
/// 32), using only uint64 multiplication functions, without overflowing. The returned result is split | ||||||||||||||
/// in 2 factors: value_hi and value_lo, one containing the upper 32 bits of the result and the other | ||||||||||||||
/// containing the lower 32 bits. | ||||||||||||||
fn multiplication_and_shift( | ||||||||||||||
mut value_hi: u64, | ||||||||||||||
mut value_lo: u64, | ||||||||||||||
mult_factor: u32, | ||||||||||||||
shift_factor: u8, | ||||||||||||||
) -> (u64, u64) { | ||||||||||||||
// multiply the integer part of value_hi by mult_factor | ||||||||||||||
value_hi = value_hi * mult_factor as u64; | ||||||||||||||
|
||||||||||||||
// the lower shift_factor bits of the result are extracted and shifted left to form the remainder. | ||||||||||||||
// value_lo is multiplied by mult_factor and right-shifted by shift_factor bits. | ||||||||||||||
// the sum of these two values forms the new lower part (value_lo) of the result. | ||||||||||||||
value_lo = (lower_bits(value_hi, shift_factor as usize) << (32 - shift_factor)) as u64 | ||||||||||||||
+ (value_lo * mult_factor as u64) | ||||||||||||||
>> shift_factor; | ||||||||||||||
|
||||||||||||||
// the right-shifted value_hi and the upper 32 bits of value_lo form the new higher part (value_hi) of the | ||||||||||||||
// result. | ||||||||||||||
value_hi = (value_hi >> shift_factor) + upper_bits(value_lo, 32); | ||||||||||||||
|
||||||||||||||
// the lower 32 bits of value_lo form the new lower part of the result. | ||||||||||||||
value_lo = lower_bits(value_lo, 32); | ||||||||||||||
|
||||||||||||||
// return the result as a fixed-point number composed of two 64-bit integers | ||||||||||||||
(value_hi, value_lo) | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
// if value == 0 or n == 0 { | ||||||||||||||
// return value | ||||||||||||||
// } | ||||||||||||||
|
||||||||||||||
// split the value into two uint64 variables to prevent overflowing | ||||||||||||||
let mut value_hi = upper_bits(value, 32); | ||||||||||||||
let mut value_lo = lower_bits(value, 32); | ||||||||||||||
|
||||||||||||||
// we keep applying the lookup table factors as long as n epochs are left | ||||||||||||||
let mut remaining_epochs = n; | ||||||||||||||
|
||||||||||||||
while remaining_epochs > 0 { | ||||||||||||||
let mut epochs_to_decay = remaining_epochs; | ||||||||||||||
|
||||||||||||||
if epochs_to_decay > 365 { | ||||||||||||||
epochs_to_decay = 365 | ||||||||||||||
} | ||||||||||||||
Comment on lines
+109
to
+113
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. or should this be using |
||||||||||||||
remaining_epochs -= epochs_to_decay; | ||||||||||||||
|
||||||||||||||
let decay_factor = self.decay_factor_at(epochs_to_decay).unwrap(); | ||||||||||||||
|
||||||||||||||
// apply the decay using fixed-point arithmetics. | ||||||||||||||
(value_hi, value_lo) = | ||||||||||||||
multiplication_and_shift(value_hi, value_lo, decay_factor, self.decay_factors().len() as u8); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
// combine both uint64 variables to get the actual value | ||||||||||||||
value_hi << 32 + value_lo | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
} | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
impl Default for ManaStructure { | ||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.