2021-01-30 21:29:59 +00:00
|
|
|
use crate::defines::LevelInt;
|
2023-04-16 17:57:21 +00:00
|
|
|
use crate::VecExt;
|
2023-04-15 12:34:42 +00:00
|
|
|
use anyhow::Result;
|
|
|
|
use anyhow_ext::ensure;
|
2022-06-19 19:34:08 +00:00
|
|
|
|
2022-07-01 15:07:22 +00:00
|
|
|
/// A growth rate defines how much experience is required per level.
|
2022-06-19 19:34:08 +00:00
|
|
|
pub trait GrowthRate {
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Calculate the level something with this growth rate would have at a certain experience.
|
2022-06-19 19:34:08 +00:00
|
|
|
fn calculate_level(&self, experience: u32) -> LevelInt;
|
2022-07-01 15:07:22 +00:00
|
|
|
/// Calculate the experience something with this growth rate would have at a certain level.
|
2023-04-15 12:34:42 +00:00
|
|
|
fn calculate_experience(&self, level: LevelInt) -> Result<u32>;
|
2022-06-19 19:34:08 +00:00
|
|
|
}
|
2021-01-30 21:29:59 +00:00
|
|
|
|
2022-07-01 15:07:22 +00:00
|
|
|
/// An implementation of the growth rate that uses a lookup table for experience.
|
2021-01-30 21:29:59 +00:00
|
|
|
pub struct LookupGrowthRate {
|
2022-07-01 15:07:22 +00:00
|
|
|
/// The lookup Vec.
|
2021-01-30 21:29:59 +00:00
|
|
|
experience: Vec<u32>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl LookupGrowthRate {
|
2022-10-14 14:53:30 +00:00
|
|
|
/// Instantiates a new lookup growth rate. The experience vec should be the amount of experience
|
|
|
|
/// required per level, with the first element being the experience required for level 1 (generally 0).
|
2021-01-30 21:29:59 +00:00
|
|
|
pub fn new(experience: Vec<u32>) -> LookupGrowthRate {
|
|
|
|
LookupGrowthRate { experience }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl GrowthRate for LookupGrowthRate {
|
|
|
|
fn calculate_level(&self, experience: u32) -> LevelInt {
|
|
|
|
for (i, v) in self.experience.iter().enumerate() {
|
|
|
|
if *v > experience {
|
|
|
|
return i as LevelInt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
self.experience.len() as LevelInt
|
|
|
|
}
|
|
|
|
|
2023-04-15 12:34:42 +00:00
|
|
|
fn calculate_experience(&self, level: LevelInt) -> Result<u32> {
|
|
|
|
ensure!(level > 0, "Level must be greater than 0, but was {}", level);
|
2022-06-06 11:54:59 +00:00
|
|
|
if level >= self.experience.len() as LevelInt {
|
2023-04-16 17:57:21 +00:00
|
|
|
match self.experience.last() {
|
|
|
|
Some(v) => Ok(*v),
|
|
|
|
None => anyhow::bail!("No experience values found"),
|
|
|
|
}
|
2022-06-06 11:54:59 +00:00
|
|
|
} else {
|
2023-04-16 17:57:21 +00:00
|
|
|
Ok(*self.experience.get_res((level - 1) as usize)?)
|
2022-06-06 11:54:59 +00:00
|
|
|
}
|
2021-01-30 21:29:59 +00:00
|
|
|
}
|
|
|
|
}
|
2022-11-28 20:34:28 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
pub(crate) mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
mockall::mock! {
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub GrowthRate {}
|
|
|
|
impl GrowthRate for GrowthRate {
|
|
|
|
fn calculate_level(&self, experience: u32) -> LevelInt;
|
2023-04-15 12:34:42 +00:00
|
|
|
fn calculate_experience(&self, level: LevelInt) -> Result<u32>;
|
2022-11-28 20:34:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|