Added buddy commands and horny license
+ clippy + fmt
This commit is contained in:
parent
2c2634925d
commit
d076318e4a
@ -33,6 +33,7 @@ pub struct BotConfig {
|
|||||||
pub guild_id: GuildId,
|
pub guild_id: GuildId,
|
||||||
pub api_addr: SocketAddr,
|
pub api_addr: SocketAddr,
|
||||||
pub announcement_channel: ChannelId,
|
pub announcement_channel: ChannelId,
|
||||||
|
pub toys: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BotConfig {
|
impl BotConfig {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
use crate::config::BotConfig;
|
use crate::config::BotConfig;
|
||||||
use crate::models::api_key::Apikey;
|
use crate::models::api_key::Apikey;
|
||||||
|
use crate::models::lil_fren::{AliveState, LilFren};
|
||||||
use crate::{command, group, GlobalData};
|
use crate::{command, group, GlobalData};
|
||||||
use json::JsonValue;
|
use json::JsonValue;
|
||||||
use serenity::client::Context;
|
use serenity::client::Context;
|
||||||
@ -9,7 +10,7 @@ use serenity::model::prelude::UserId;
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
#[group]
|
#[group]
|
||||||
#[commands(reload, dump_db, load_db, add_key)]
|
#[commands(reload, dump_db, load_db, add_key, debug_buddy)]
|
||||||
pub struct ADMIN;
|
pub struct ADMIN;
|
||||||
|
|
||||||
pub fn is_admin(user_id: &UserId, cfg: &BotConfig) -> bool {
|
pub fn is_admin(user_id: &UserId, cfg: &BotConfig) -> bool {
|
||||||
@ -127,3 +128,36 @@ async fn add_key(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description("Check little buddy stats")]
|
||||||
|
async fn debug_buddy(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
||||||
|
let mut data = ctx.data.write().await;
|
||||||
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
|
|
||||||
|
let lil_fren = LilFren::get_lil_fren(&global_data.db)?;
|
||||||
|
|
||||||
|
if let Some(lil_fren) = lil_fren {
|
||||||
|
if lil_fren.is_alive() == AliveState::Alive {
|
||||||
|
msg.reply(
|
||||||
|
&ctx.http,
|
||||||
|
format!(
|
||||||
|
"Hunger: {} Thirst: {} Entertainment: {} Smarts: {} Metabolism: {} State: {:?}",
|
||||||
|
lil_fren.hunger,
|
||||||
|
lil_fren.thirst,
|
||||||
|
lil_fren.entertainment,
|
||||||
|
lil_fren.smarts,
|
||||||
|
lil_fren.metabolism,
|
||||||
|
lil_fren.state
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Lil buddy is dead!").await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Sorry no little buddy found!").await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
208
src/discord/little_fren.rs
Normal file
208
src/discord/little_fren.rs
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
use crate::config::GlobalData;
|
||||||
|
use crate::models::lil_fren;
|
||||||
|
use crate::models::lil_fren::{AliveState, LilFren, LilFrenState};
|
||||||
|
use crate::{command, group};
|
||||||
|
use rand::prelude::SliceRandom;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
use serenity::client::Context;
|
||||||
|
use serenity::framework::standard::{Args, CommandResult};
|
||||||
|
use serenity::model::channel::Message;
|
||||||
|
use serenity::model::misc::EmojiIdentifier;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
|
||||||
|
#[group]
|
||||||
|
#[commands(adopt, checkup, feed, give_water, play)]
|
||||||
|
pub struct Buddy;
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description("Adopt a new lil buddy")]
|
||||||
|
#[only_in(guilds)]
|
||||||
|
async fn adopt(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
|
let mut data = ctx.data.write().await;
|
||||||
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
|
|
||||||
|
if let Ok(emoji) = args.parse::<EmojiIdentifier>() {
|
||||||
|
if let Some(lil_fren) = LilFren::get_lil_fren(&global_data.db)? {
|
||||||
|
if lil_fren.is_alive() == AliveState::Alive {
|
||||||
|
msg.reply(
|
||||||
|
&ctx.http,
|
||||||
|
"Your buddy is still alive, please take care of him :)",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LilFren::create_new_lil_fren(&global_data.db, emoji.id)?;
|
||||||
|
let guild = msg.guild_id.unwrap();
|
||||||
|
let emoji = guild.emoji(&ctx.http, emoji.id).await?;
|
||||||
|
|
||||||
|
let mut msg_builder = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg_builder.push("Congrats on adopting ");
|
||||||
|
msg_builder.emoji(&emoji);
|
||||||
|
msg_builder.push("!");
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, msg_builder.build()).await?;
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Sorry whatever that is not adoptable.")
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[only_in(guilds)]
|
||||||
|
#[description("Checkup on your lil buddy")]
|
||||||
|
async fn checkup(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
||||||
|
let mut data = ctx.data.write().await;
|
||||||
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
|
|
||||||
|
let lil_fren = LilFren::get_lil_fren(&global_data.db)?;
|
||||||
|
|
||||||
|
if let Some(lil_fren) = lil_fren {
|
||||||
|
let guild = msg.guild_id.unwrap();
|
||||||
|
let alive_state = lil_fren.is_alive();
|
||||||
|
|
||||||
|
if alive_state == AliveState::Alive {
|
||||||
|
let state_msg = match lil_fren.state {
|
||||||
|
LilFrenState::Standing => "Little buddy is standing.",
|
||||||
|
LilFrenState::TaxFraud => "Your buddy is comiting tax fraud",
|
||||||
|
LilFrenState::Sick => "Oh no! Buddy is sick!",
|
||||||
|
LilFrenState::Dancing => "Buddy got some moves!",
|
||||||
|
LilFrenState::Sleep => "Shhh, buddy is asleep",
|
||||||
|
};
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, state_msg).await?;
|
||||||
|
msg.reply(&ctx.http, lil_fren.draw(ctx, &guild).await)
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
let resp = match alive_state {
|
||||||
|
AliveState::Alive => "",
|
||||||
|
AliveState::DiedOfBoredom => "Your little buddy died of boredom RIP",
|
||||||
|
AliveState::DiedOfHunger => "Your little buddy died of hunger RIP",
|
||||||
|
AliveState::DiedOfThirst => "Your little buddy died of thirst",
|
||||||
|
};
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, resp).await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.reply(
|
||||||
|
&ctx.http,
|
||||||
|
"Sorry you have no little buddy right now. Please adopt!",
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description("Feed lil buddy")]
|
||||||
|
async fn feed(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
||||||
|
let mut data = ctx.data.write().await;
|
||||||
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
|
|
||||||
|
if let Ok(food_emoji) = args.parse::<String>() {
|
||||||
|
let lil_fren = LilFren::get_lil_fren(&global_data.db)?;
|
||||||
|
|
||||||
|
if let Some(mut lil_fren) = lil_fren {
|
||||||
|
if lil_fren.is_alive() == AliveState::Alive {
|
||||||
|
let feed: f32 = thread_rng().gen_range(-0.1..=1.0);
|
||||||
|
lil_fren.hunger = (lil_fren.hunger + feed).clamp(-1.0, 1.0);
|
||||||
|
let guild = msg.guild_id.unwrap();
|
||||||
|
|
||||||
|
let lil_fren_emoji = guild.emoji(&ctx.http, lil_fren.emoji).await?;
|
||||||
|
|
||||||
|
if feed > 0.0 {
|
||||||
|
msg.reply(&ctx.http, "Lil buddy seemed to like that!")
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Lil buddy DID not like that!").await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, lil_fren::draw_feed(&lil_fren_emoji, &food_emoji))
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
global_data.db.insert(lil_fren)?;
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "You may want to check on your buddy...")
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Sorry no little buddy found!").await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Please provide something to feed lil buddy")
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description("Give lil buddy some water")]
|
||||||
|
async fn give_water(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
||||||
|
let mut data = ctx.data.write().await;
|
||||||
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
|
|
||||||
|
let lil_fren = LilFren::get_lil_fren(&global_data.db)?;
|
||||||
|
|
||||||
|
if let Some(mut lil_fren) = lil_fren {
|
||||||
|
if lil_fren.is_alive() == AliveState::Alive {
|
||||||
|
lil_fren.thirst = (lil_fren.thirst + 0.5).clamp(-1.0, 1.0);
|
||||||
|
let guild = msg.guild_id.unwrap();
|
||||||
|
|
||||||
|
let lil_fren_emoji = guild.emoji(&ctx.http, lil_fren.emoji).await?;
|
||||||
|
|
||||||
|
msg.reply(&ctx.http, "Lil buddy be drinking!").await?;
|
||||||
|
global_data.db.insert(lil_fren)?;
|
||||||
|
|
||||||
|
msg.reply(
|
||||||
|
&ctx.http,
|
||||||
|
lil_fren::draw_feed(&lil_fren_emoji, ":cup_with_straw:"),
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "You may want to check on your buddy...")
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Sorry no little buddy found!").await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[command]
|
||||||
|
#[description("Play with buddy")]
|
||||||
|
async fn play(ctx: &Context, msg: &Message, _args: Args) -> CommandResult {
|
||||||
|
let mut data = ctx.data.write().await;
|
||||||
|
let global_data = data.get_mut::<GlobalData>().unwrap();
|
||||||
|
|
||||||
|
let lil_fren = LilFren::get_lil_fren(&global_data.db)?;
|
||||||
|
|
||||||
|
if let Some(mut lil_fren) = lil_fren {
|
||||||
|
if lil_fren.is_alive() == AliveState::Alive {
|
||||||
|
lil_fren.entertainment =
|
||||||
|
(lil_fren.entertainment + thread_rng().gen_range(-0.10..1.0)).clamp(-1.0, 1.0);
|
||||||
|
let guild = msg.guild_id.unwrap();
|
||||||
|
|
||||||
|
let lil_fren_emoji = guild.emoji(&ctx.http, lil_fren.emoji).await?;
|
||||||
|
|
||||||
|
global_data.db.insert(lil_fren)?;
|
||||||
|
|
||||||
|
let toy = global_data.cfg.toys.choose(&mut thread_rng()).unwrap();
|
||||||
|
msg.reply(&ctx.http, lil_fren::draw_feed(&lil_fren_emoji, toy))
|
||||||
|
.await?;
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "You may want to check on your buddy...")
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
msg.reply(&ctx.http, "Sorry no little buddy found!").await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ pub mod color;
|
|||||||
pub mod emoji_race;
|
pub mod emoji_race;
|
||||||
pub mod fren_coin;
|
pub mod fren_coin;
|
||||||
pub mod joke;
|
pub mod joke;
|
||||||
|
pub mod little_fren;
|
||||||
pub mod motivate;
|
pub mod motivate;
|
||||||
pub mod shop;
|
pub mod shop;
|
||||||
pub mod story;
|
pub mod story;
|
||||||
@ -17,6 +18,7 @@ use crate::discord::joke::random;
|
|||||||
use crate::discord::shop::restock_shop;
|
use crate::discord::shop::restock_shop;
|
||||||
use crate::models::birthday::BirthdayEntry;
|
use crate::models::birthday::BirthdayEntry;
|
||||||
use crate::models::insult_compliment::{RandomResponseTemplate, ResponseType};
|
use crate::models::insult_compliment::{RandomResponseTemplate, ResponseType};
|
||||||
|
use crate::models::lil_fren::lil_fren_task;
|
||||||
use crate::{help, hook, GlobalData};
|
use crate::{help, hook, GlobalData};
|
||||||
use chrono::{Days, TimeZone, Timelike, Utc};
|
use chrono::{Days, TimeZone, Timelike, Utc};
|
||||||
use rand::prelude::IteratorRandom;
|
use rand::prelude::IteratorRandom;
|
||||||
@ -42,6 +44,13 @@ static ERROR_MSG: &str =
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl EventHandler for Handler {
|
impl EventHandler for Handler {
|
||||||
async fn cache_ready(&self, ctx: Context, _guilds: Vec<GuildId>) {
|
async fn cache_ready(&self, ctx: Context, _guilds: Vec<GuildId>) {
|
||||||
|
let ctx1 = ctx.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
loop {
|
||||||
|
lil_fren_task(&ctx1).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
let mut next_check = chrono_tz::America::Chicago
|
let mut next_check = chrono_tz::America::Chicago
|
||||||
.from_utc_datetime(&Utc::now().naive_utc())
|
.from_utc_datetime(&Utc::now().naive_utc())
|
||||||
|
|||||||
@ -214,6 +214,9 @@ async fn use_item(ctx: &Context, msg: &Message, args: Args) -> CommandResult {
|
|||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ItemType::LicenseToBeHorny => {
|
||||||
|
msg.reply(&ctx.http, "https://media.discordapp.net/attachments/840015650286075945/1127022083919069184/Img_2022_10_21_05_08_12.jpg").await?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -32,6 +32,7 @@ pub enum ItemType {
|
|||||||
TheConceptOfLove,
|
TheConceptOfLove,
|
||||||
GoodFortune,
|
GoodFortune,
|
||||||
Nft,
|
Nft,
|
||||||
|
LicenseToBeHorny,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Hash, Eq, PartialEq, Copy)]
|
#[derive(Debug, Clone, Hash, Eq, PartialEq, Copy)]
|
||||||
@ -56,6 +57,8 @@ impl FromStr for ItemType {
|
|||||||
Ok(ItemType::GoodFortune)
|
Ok(ItemType::GoodFortune)
|
||||||
} else if item.starts_with("nft") {
|
} else if item.starts_with("nft") {
|
||||||
Ok(ItemType::Nft)
|
Ok(ItemType::Nft)
|
||||||
|
} else if item.starts_with("licensetobehorny") {
|
||||||
|
Ok(ItemType::LicenseToBeHorny)
|
||||||
} else {
|
} else {
|
||||||
Err(InventoryError::UnkownItem)
|
Err(InventoryError::UnkownItem)
|
||||||
}
|
}
|
||||||
@ -69,6 +72,7 @@ impl Display for ItemType {
|
|||||||
ItemType::TheConceptOfLove => "The Concept of Love".to_string(),
|
ItemType::TheConceptOfLove => "The Concept of Love".to_string(),
|
||||||
ItemType::GoodFortune => "Good Fortune".to_string(),
|
ItemType::GoodFortune => "Good Fortune".to_string(),
|
||||||
ItemType::Nft => "NFT".to_string(),
|
ItemType::Nft => "NFT".to_string(),
|
||||||
|
ItemType::LicenseToBeHorny => "License to be Horny".to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(f, "{}", name)
|
write!(f, "{}", name)
|
||||||
@ -88,6 +92,7 @@ impl InventorySlot {
|
|||||||
ItemType::TheConceptOfLove => 300,
|
ItemType::TheConceptOfLove => 300,
|
||||||
ItemType::GoodFortune => 75,
|
ItemType::GoodFortune => 75,
|
||||||
ItemType::Nft => 100,
|
ItemType::Nft => 100,
|
||||||
|
ItemType::LicenseToBeHorny => 100,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,7 @@ async fn main() {
|
|||||||
.group(&discord::voices::VOICES_GROUP)
|
.group(&discord::voices::VOICES_GROUP)
|
||||||
.group(&discord::shop::SHOP_GROUP)
|
.group(&discord::shop::SHOP_GROUP)
|
||||||
.group(&discord::birthday::BIRTHDAY_GROUP)
|
.group(&discord::birthday::BIRTHDAY_GROUP)
|
||||||
|
.group(&discord::little_fren::BUDDY_GROUP)
|
||||||
.unrecognised_command(unrecognised_command_hook)
|
.unrecognised_command(unrecognised_command_hook)
|
||||||
.bucket("bad_apple", |b| b.delay(60 * 10))
|
.bucket("bad_apple", |b| b.delay(60 * 10))
|
||||||
.await
|
.await
|
||||||
|
|||||||
267
src/models/lil_fren.rs
Normal file
267
src/models/lil_fren.rs
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
use crate::config::GlobalData;
|
||||||
|
use crate::error::Error;
|
||||||
|
use j_db::database::Database;
|
||||||
|
use j_db::model::JdbModel;
|
||||||
|
use rand::distributions::Standard;
|
||||||
|
use rand::prelude::Distribution;
|
||||||
|
use rand::{thread_rng, Rng};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serenity::model::guild::Emoji;
|
||||||
|
use serenity::model::id::{EmojiId, GuildId};
|
||||||
|
use serenity::prelude::Context;
|
||||||
|
use serenity::utils::MessageBuilder;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
pub fn draw_standing(emoji: &Emoji) -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push(":blue_square::blue_square:");
|
||||||
|
msg.emoji(emoji);
|
||||||
|
msg.push_line(":blue_square::blue_square:");
|
||||||
|
msg.push_line(":green_square::green_square::green_square::green_square::green_square:");
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_dancing(emoji: &Emoji) -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::notes::blue_square:");
|
||||||
|
msg.push_line(":blue_square::notes::blue_square::notes::blue_square:");
|
||||||
|
msg.push(":blue_square::blue_square:");
|
||||||
|
msg.emoji(emoji);
|
||||||
|
msg.push_line(":blue_square::blue_square:");
|
||||||
|
msg.push_line(":green_square::green_square::green_square::green_square::green_square:");
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_tax_fraud(emoji: &Emoji) -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push(":blue_square::page_with_curl:");
|
||||||
|
msg.emoji(emoji);
|
||||||
|
msg.push_line(":blue_square::blue_square:");
|
||||||
|
msg.push_line(":green_square::green_square::green_square::green_square::green_square:");
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_sick(emoji: &Emoji) -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push(":blue_square::bucket:");
|
||||||
|
msg.emoji(emoji);
|
||||||
|
msg.push_line(":roll_of_paper::blue_square:");
|
||||||
|
msg.push_line(":green_square::green_square::green_square::green_square::green_square:");
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_sleep(emoji: &Emoji) -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push(":blue_square::blue_square:");
|
||||||
|
msg.emoji(emoji);
|
||||||
|
msg.push_line(":blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::bed::blue_square::blue_square:");
|
||||||
|
msg.push_line(":green_square::green_square::green_square::green_square::green_square:");
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_dead() -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::headstone::blue_square::blue_square:");
|
||||||
|
msg.push_line(":green_square::green_square::green_square::green_square::green_square:");
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw_feed(emoji: &Emoji, food: &str) -> String {
|
||||||
|
let mut msg = MessageBuilder::new();
|
||||||
|
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push_line(":blue_square::blue_square::blue_square::blue_square::blue_square:");
|
||||||
|
msg.push(":blue_square::blue_square:");
|
||||||
|
msg.emoji(emoji);
|
||||||
|
msg.push(food);
|
||||||
|
msg.push_line(":blue_square:");
|
||||||
|
msg.push_line(":green_square::green_square::green_square::green_square::green_square:");
|
||||||
|
|
||||||
|
msg.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone, PartialOrd, PartialEq)]
|
||||||
|
pub enum LilFrenState {
|
||||||
|
Standing,
|
||||||
|
TaxFraud,
|
||||||
|
Sick,
|
||||||
|
Dancing,
|
||||||
|
Sleep,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialOrd, PartialEq)]
|
||||||
|
pub enum AliveState {
|
||||||
|
Alive,
|
||||||
|
DiedOfBoredom,
|
||||||
|
DiedOfHunger,
|
||||||
|
DiedOfThirst,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Distribution<LilFrenState> for Standard {
|
||||||
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> LilFrenState {
|
||||||
|
match rng.gen_range(0..100) {
|
||||||
|
0..=30 => LilFrenState::Standing,
|
||||||
|
31..=40 => LilFrenState::TaxFraud,
|
||||||
|
41..=50 => LilFrenState::Sick,
|
||||||
|
51..=70 => LilFrenState::Dancing,
|
||||||
|
_ => LilFrenState::Sleep,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, Clone)]
|
||||||
|
pub struct LilFren {
|
||||||
|
id: Option<u64>,
|
||||||
|
pub emoji: EmojiId,
|
||||||
|
pub hunger: f32,
|
||||||
|
pub thirst: f32,
|
||||||
|
pub entertainment: f32,
|
||||||
|
|
||||||
|
pub state: LilFrenState,
|
||||||
|
pub smarts: f32,
|
||||||
|
pub metabolism: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl JdbModel for LilFren {
|
||||||
|
fn id(&self) -> Option<u64> {
|
||||||
|
self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_id(&mut self, id: u64) {
|
||||||
|
self.id = Some(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree() -> String {
|
||||||
|
"LilFren".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LilFren {
|
||||||
|
pub fn new(emoji: EmojiId) -> Self {
|
||||||
|
Self {
|
||||||
|
id: None,
|
||||||
|
emoji,
|
||||||
|
hunger: 1.0,
|
||||||
|
thirst: 1.0,
|
||||||
|
entertainment: 1.0,
|
||||||
|
state: LilFrenState::Standing,
|
||||||
|
smarts: thread_rng().gen_range(0.1..1.0),
|
||||||
|
metabolism: thread_rng().gen_range(0.1..1.0),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_new_lil_fren(db: &Database, emoji: EmojiId) -> Result<Self, Error> {
|
||||||
|
let lil_fren: Option<Self> = Self::get_lil_fren(db)?;
|
||||||
|
|
||||||
|
if let Some(lil_fren) = lil_fren {
|
||||||
|
db.remove::<LilFren>(lil_fren.id().unwrap())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let lil_fren = db.insert(Self::new(emoji))?;
|
||||||
|
|
||||||
|
Ok(lil_fren)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_lil_fren(db: &Database) -> Result<Option<Self>, Error> {
|
||||||
|
Ok(db.filter(|_, _fren: &Self| true)?.next())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_fren(&mut self, db: &Database) -> Result<(), Error> {
|
||||||
|
if let Some(mut lil_fren) = Self::get_lil_fren(db)? {
|
||||||
|
let (hunger_diff, thirst_diff, entertainment_diff) = match lil_fren.state {
|
||||||
|
LilFrenState::Standing => (-0.01, -0.02, -0.01),
|
||||||
|
LilFrenState::TaxFraud => (-0.01, -0.02, 0.01),
|
||||||
|
LilFrenState::Sick => (-0.1, -0.15, -0.01),
|
||||||
|
LilFrenState::Dancing => (-0.05, -0.8, 0.05),
|
||||||
|
LilFrenState::Sleep => (-0.005, -0.01, 0.00),
|
||||||
|
};
|
||||||
|
|
||||||
|
lil_fren.hunger -= hunger_diff * self.metabolism;
|
||||||
|
lil_fren.thirst -= thirst_diff * self.metabolism;
|
||||||
|
lil_fren.entertainment -= entertainment_diff * self.smarts;
|
||||||
|
|
||||||
|
if thread_rng().gen_bool(0.75) {
|
||||||
|
println!("fren is now {:?}", self.state);
|
||||||
|
lil_fren.state = thread_rng().gen();
|
||||||
|
}
|
||||||
|
|
||||||
|
db.insert(lil_fren)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_alive(&self) -> AliveState {
|
||||||
|
if self.thirst < 0.0 {
|
||||||
|
AliveState::DiedOfThirst
|
||||||
|
} else if self.entertainment < 0.0 {
|
||||||
|
AliveState::DiedOfBoredom
|
||||||
|
} else if self.hunger < 0.0 {
|
||||||
|
AliveState::DiedOfHunger
|
||||||
|
} else {
|
||||||
|
AliveState::Alive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw_activity(&self, emoji: &Emoji) -> String {
|
||||||
|
match self.state {
|
||||||
|
LilFrenState::Standing => draw_standing(emoji),
|
||||||
|
LilFrenState::TaxFraud => draw_tax_fraud(emoji),
|
||||||
|
LilFrenState::Sick => draw_sick(emoji),
|
||||||
|
LilFrenState::Dancing => draw_dancing(emoji),
|
||||||
|
LilFrenState::Sleep => draw_sleep(emoji),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn draw(&self, ctx: &Context, guild: &GuildId) -> String {
|
||||||
|
let emoji = guild.emoji(&ctx.http, self.emoji).await.unwrap();
|
||||||
|
let alive_state = self.is_alive();
|
||||||
|
|
||||||
|
if let AliveState::Alive = alive_state {
|
||||||
|
self.draw_activity(&emoji)
|
||||||
|
} else {
|
||||||
|
draw_dead()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn lil_fren_task(ctx: &Context) {
|
||||||
|
tokio::time::sleep(Duration::from_secs(60)).await;
|
||||||
|
let data = ctx.data.read().await;
|
||||||
|
let global_data = data.get::<GlobalData>().unwrap();
|
||||||
|
|
||||||
|
let fren = LilFren::get_lil_fren(&global_data.db).unwrap();
|
||||||
|
|
||||||
|
if let Some(mut fren) = fren {
|
||||||
|
fren.update_fren(&global_data.db).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
pub mod api_key;
|
pub mod api_key;
|
||||||
pub mod birthday;
|
pub mod birthday;
|
||||||
pub mod insult_compliment;
|
pub mod insult_compliment;
|
||||||
|
pub mod lil_fren;
|
||||||
pub mod motivation;
|
pub mod motivation;
|
||||||
pub mod random;
|
pub mod random;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user