134 lines
3.4 KiB
Rust
134 lines
3.4 KiB
Rust
use anyhow::Result;
|
|
use engine::prelude::*;
|
|
|
|
use image::RgbaImage;
|
|
|
|
use std::{fmt, slice::Iter};
|
|
|
|
use crate::config::items::{ItemSettings, RarityColorSettings};
|
|
|
|
use super::{ability_book::Ability, ItemSystem};
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
pub enum Rarities {
|
|
Common,
|
|
Uncommon,
|
|
Magical,
|
|
Rare,
|
|
Epic,
|
|
Legendary,
|
|
}
|
|
|
|
impl Rarities {
|
|
const COUNT: u32 = 6;
|
|
|
|
pub fn iter() -> Iter<'static, Rarities> {
|
|
use Rarities::*;
|
|
|
|
static RARITIES: [Rarities; Rarities::COUNT as usize] =
|
|
[Common, Uncommon, Magical, Rare, Epic, Legendary];
|
|
RARITIES.iter()
|
|
}
|
|
|
|
pub fn random(item_settings: &ItemSettings, level: u32) -> Self {
|
|
let p = Coin::raw();
|
|
let multiplier = level as f32 / item_settings.general.drop_chance_reference_level as f32;
|
|
|
|
// legendary
|
|
let mut lower = 0.0;
|
|
let mut upper = item_settings.rarity_drop_rates.legendary * multiplier;
|
|
|
|
if Self::is_between(p, lower, upper) {
|
|
return Self::Legendary;
|
|
}
|
|
|
|
// epic
|
|
lower = upper;
|
|
upper = upper + item_settings.rarity_drop_rates.epic * multiplier;
|
|
|
|
if Self::is_between(p, lower, upper) {
|
|
return Self::Epic;
|
|
}
|
|
|
|
// rare
|
|
lower = upper;
|
|
upper = upper + item_settings.rarity_drop_rates.rare * multiplier;
|
|
|
|
if Self::is_between(p, lower, upper) {
|
|
return Self::Rare;
|
|
}
|
|
|
|
// magical
|
|
lower = upper;
|
|
upper = upper + item_settings.rarity_drop_rates.magical * multiplier;
|
|
|
|
if Self::is_between(p, lower, upper) {
|
|
return Self::Magical;
|
|
}
|
|
|
|
// uncommon
|
|
lower = upper;
|
|
upper = upper + item_settings.rarity_drop_rates.uncommon * multiplier;
|
|
|
|
if Self::is_between(p, lower, upper) {
|
|
return Self::Uncommon;
|
|
}
|
|
|
|
// common
|
|
Self::Common
|
|
}
|
|
|
|
#[inline]
|
|
fn is_between(p: f32, l: f32, h: f32) -> bool {
|
|
p >= l && p <= h
|
|
}
|
|
|
|
pub(crate) fn apply_color<A: Ability>(
|
|
&self,
|
|
base_image: &RgbaImage,
|
|
rarity_color_settings: &RarityColorSettings,
|
|
) -> RgbaImage {
|
|
ItemSystem::<A>::apply_color(base_image, rarity_color_settings.from_rarity(*self))
|
|
}
|
|
}
|
|
|
|
impl Default for Rarities {
|
|
fn default() -> Self {
|
|
Self::Common
|
|
}
|
|
}
|
|
|
|
impl std::str::FromStr for Rarities {
|
|
type Err = anyhow::Error;
|
|
|
|
fn from_str(s: &str) -> Result<Self> {
|
|
match s {
|
|
"Common" => Ok(Self::Common),
|
|
"Uncommon" => Ok(Self::Uncommon),
|
|
"Magical" => Ok(Self::Magical),
|
|
"Rare" => Ok(Self::Rare),
|
|
"Epic" => Ok(Self::Epic),
|
|
"Legendary" => Ok(Self::Legendary),
|
|
|
|
_ => {
|
|
return Err(anyhow::Error::msg(format!(
|
|
"Failed parsing Rarities from {}",
|
|
s
|
|
)))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for Rarities {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
match *self {
|
|
Self::Common => write!(f, "Common"),
|
|
Self::Uncommon => write!(f, "Uncommon"),
|
|
Self::Magical => write!(f, "Magical"),
|
|
Self::Rare => write!(f, "Rare"),
|
|
Self::Epic => write!(f, "Epic"),
|
|
Self::Legendary => write!(f, "Legendary"),
|
|
}
|
|
}
|
|
}
|