use crate::error::Error; use j_db::database::Database; use j_db::model::JdbModel; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::fmt::{Debug, Display, Formatter}; use std::str::FromStr; use strum::EnumIter; #[derive(Debug)] pub enum ImprovementError { UnknownImprovement, } impl Display for ImprovementError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match self { ImprovementError::UnknownImprovement => write!( f, "I don't know what that improvement is, sounds lame and cringe!" ), } } } impl std::error::Error for ImprovementError {} #[derive(Debug, Deserialize, Serialize, Clone, Hash, Eq, PartialEq, Copy, EnumIter)] pub enum ImprovementType { GogurtNightMarket, LilBuddyAutoFeeder, FriendshipTower, JotchuaCollegeFund, } impl ImprovementType { pub fn description(&self) -> String { match self { ImprovementType::GogurtNightMarket => { "Keep the Gogurt Market open until 11 PM NST".to_string() } ImprovementType::LilBuddyAutoFeeder => { "Buy an auto-feeder for Lil Buddy to keep them fed!".to_string() } ImprovementType::FriendshipTower => "Make the Friendship Tower taller!!".to_string(), ImprovementType::JotchuaCollegeFund => { "Contribute to Jotchua's college fund!".to_string() } } } pub fn price(&self) -> u64 { match self { ImprovementType::GogurtNightMarket => 200_000, ImprovementType::LilBuddyAutoFeeder => 150_000, ImprovementType::FriendshipTower => 50_000, ImprovementType::JotchuaCollegeFund => 1_000, } } pub fn has_levels(&self) -> bool { #[allow(clippy::match_like_matches_macro)] match self { ImprovementType::FriendshipTower => true, _ => false, } } pub fn name(&self) -> String { match self { ImprovementType::GogurtNightMarket => "Gogurt Night Market".to_string(), ImprovementType::LilBuddyAutoFeeder => "Autofeeder".to_string(), ImprovementType::FriendshipTower => "Friendship Tower".to_string(), ImprovementType::JotchuaCollegeFund => "Jotchua College Fund".to_string(), } } pub fn post_buy_description(&self) -> String { match self { ImprovementType::GogurtNightMarket => "Congrats on investing in the night market. The first day of night trading will start tomorrow!".to_string(), ImprovementType::LilBuddyAutoFeeder => "Very kind of you, Lil Buddy will never starve again.".to_string(), ImprovementType::FriendshipTower => "ANOTHER GLORIOUS FLOOR FOR THE TOWER, MAY IT EVER GET CLOSER TO GOD".to_string(), ImprovementType::JotchuaCollegeFund => "Jotchua thanks you!!!".to_string() } } } impl FromStr for ImprovementType { type Err = ImprovementError; fn from_str(s: &str) -> Result { let name = s.to_lowercase(); match name.as_str() { "gogurt night market" => Ok(Self::GogurtNightMarket), "autofeeder" => Ok(Self::LilBuddyAutoFeeder), "friendship tower" => Ok(Self::FriendshipTower), "jotchua college fund" => Ok(Self::JotchuaCollegeFund), _ => Err(ImprovementError::UnknownImprovement), } } } #[derive(Debug, Deserialize, Serialize, Clone, Eq, PartialEq)] pub struct Improvement { pub level: u32, } #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Improvements { id: Option, pub improvements: HashMap, } impl Improvements { pub fn get_improvement_config(db: &Database) -> Result { Ok(db.filter(|_, _: &Self| true)?.next().unwrap_or(Self { id: None, improvements: HashMap::new(), })) } pub fn get_improvement( db: &Database, improvement_type: ImprovementType, ) -> Result, Error> { let improvements = Self::get_improvement_config(db)?; Ok(improvements.improvements.get(&improvement_type).cloned()) } pub fn increment_improvement( db: &Database, improvement_type: ImprovementType, ) -> Result { let mut improvements = Self::get_improvement_config(db)?; let entry = improvements .improvements .entry(improvement_type) .or_insert(Improvement { level: 1 }) .clone(); db.insert(improvements)?; Ok(entry.level) } pub fn has_improvement( db: &Database, improvement_type: ImprovementType, ) -> Result { Ok(Self::get_improvement(db, improvement_type)?.is_some()) } } impl JdbModel for Improvements { fn id(&self) -> Option { self.id } fn set_id(&mut self, id: u64) { self.id = Some(id) } fn tree() -> String { "Improvements".to_string() } fn check_unique(&self, _: &Self) -> bool { false } }