use anyhow::Result; use engine::prelude::*; use image::RgbaImage; use std::{fmt, slice::Iter}; use crate::config::items::{ItemSettings, RarityColorSettings}; use super::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 fn apply_color( &self, base_image: &RgbaImage, rarity_color_settings: &RarityColorSettings, ) -> RgbaImage { ItemSystem::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 { 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"), } } }