pub mod balance; pub mod give; pub mod wager; pub mod daily; pub mod leaderboard; pub mod shop; pub mod blackjack; use crate::{inventory::{self, Inventory}, common::{Context, Error}}; use poise::serenity_prelude::{self as serenity, futures::StreamExt, UserId}; use sqlx::PgConnection; use std::collections::HashMap; #[derive(Clone)] pub enum Effect { Multiplier(f64), Chance(f64), } #[derive(Clone)] pub struct Item { pub name: &'static str, pub desc: &'static str, pub effects: &'static [Effect], pub id: u64, } impl Item { pub fn inv_item(self) -> inventory::Item { inventory::Item { id: 0, name: self.name.to_string(), game: ID as i64, item: self.id as i64, data: serde_json::json!({}), } } } const ID: u64 = 440; mod items { use super::{Item, Effect}; pub const DIRT: Item = Item { name: "Pile of Dirt", desc: "Returns a 1.01x multiplier on all earnings", effects: &[Effect::Multiplier(1.01)], id: id::DIRT, }; pub const SAND: Item = Item { name: "Pile of Sand", desc: "Increase your odds of winning by 1%", effects: &[Effect::Chance(0.51)], id: id::SAND, }; mod id { pub const DIRT: u64 = 1; pub const SAND: u64 = 2; } pub fn get_item_by_id(id: u64) -> Option<&'static Item> { match id { id::DIRT => Some(&DIRT), id::SAND => Some(&SAND), _ => None } } pub fn get_item_by_name(name: &str) -> Option<&'static Item> { match name { "Pile of Dirt" => Some(&DIRT), "Pile of Sand" => Some(&SAND), _ => None } } } pub async fn get_balance(id: UserId, db: &mut PgConnection) -> Result { let row = sqlx::query!( "SELECT balance FROM bank WHERE id = $1", id.get() as i64 ).fetch_one(db).await.ok(); let balance = if let Some(row) = row { row.balance.unwrap_or(100) } else { 100 }; Ok(balance) } pub async fn change_balance(id: UserId, balance: i32, db: &mut PgConnection) -> Result<(), Error> { sqlx::query!( r#"INSERT INTO bank (id, balance) VALUES ($1, $2) ON CONFLICT (id) DO UPDATE SET balance = EXCLUDED.balance"#, id.get() as i64, balance ).execute(db).await?; Ok(()) } async fn autocomplete_inventory<'a>( ctx: Context<'a>, partial: &'a str, ) -> impl Iterator + use<'a> { let db = &ctx.data().database; let inventory = Inventory::new(ctx.author().id, Some(ID)) .items(db).await .fold(HashMap::::new(), |mut acc, item| async { let item = item.unwrap(); let x = acc.get(&item.item); acc.insert(item.item, x.map(|x| x + 1).unwrap_or(1)); acc }).await; inventory.into_iter() .map(|(id, count)| (items::get_item_by_id(id as u64).unwrap(), count)) .filter(move |(item, _)| item.name.contains(partial)) .map(|(item, count)| serenity::AutocompleteChoice::new( format!("{} - {} ({count}x)", item.desc, item.name), item.name )) }