FrenBot/src/discord/little_fren.rs
2026-05-03 16:18:04 -06:00

249 lines
8.0 KiB
Rust

use crate::discord::{Context, is_not_cancelled};
use crate::error::Error;
use crate::models::lil_fren;
use crate::models::lil_fren::{AliveState, LilFren, LilFrenState};
use poise::serenity_prelude::model::misc::EmojiIdentifier;
use poise::serenity_prelude::utils::MessageBuilder;
use rand::prelude::IndexedRandom;
use rand::rng;
/// Adopt a new little buddy!
#[poise::command(
prefix_command,
guild_only,
category = "Lil Buddy",
check = "is_not_cancelled"
)]
pub async fn adopt(
ctx: Context<'_>,
#[description = "Lil buddy to adopt"] lil_buddy: EmojiIdentifier,
) -> Result<(), Error> {
if let Some(lil_fren) = LilFren::get_lil_fren(&ctx.data().db)?
&& lil_fren.is_alive() == AliveState::Alive
{
ctx.reply("Your buddy is still alive, please take care of him :)")
.await?;
return Ok(());
}
LilFren::create_new_lil_fren(&ctx.data().db, lil_buddy.id)?;
let guild = ctx.guild_id().unwrap();
let emoji = guild.emoji(&ctx, lil_buddy.id).await?;
let mut msg_builder = MessageBuilder::new();
msg_builder.push("Congrats on adopting ");
msg_builder.emoji(&emoji);
msg_builder.push("!");
ctx.reply(msg_builder.build()).await?;
Ok(())
}
/// Checkup on your little buddy!
#[poise::command(
prefix_command,
guild_only,
category = "Lil Buddy",
check = "is_not_cancelled"
)]
pub async fn checkup(ctx: Context<'_>) -> Result<(), Error> {
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
if let Some(lil_fren) = lil_fren {
let guild = ctx.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",
LilFrenState::Magic => "Wizard Buddy loves casting spells",
LilFrenState::AttemptingToCircumventDeath => {
"Buddy appears to be researching how to be come immortal"
}
LilFrenState::AttemptingToNotCauseAResonanceCascade => {
"Lil buddy is trying to prevent a resonance cascade"
}
LilFrenState::Mining => "Lil buddy found some diamonds!",
LilFrenState::PhasedIntoYourReality => {
"Lil Buddy has phased into your reality, they will be back soon"
}
LilFrenState::Mugging => "Uh-oh. Looks like buddy is mugging someone again...",
LilFrenState::LostABalloon => {
"Buddy lost their balloon :(, I hope this doesn't cause an international incident"
}
};
ctx.reply(state_msg).await?;
ctx.reply(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",
};
ctx.reply(resp).await?;
}
} else {
ctx.reply("Sorry you have no little buddy right now. Please adopt, don't shop!")
.await?;
}
Ok(())
}
/// Feed your little buddy something totally normal!
#[poise::command(
prefix_command,
guild_only,
category = "Lil Buddy",
check = "is_not_cancelled"
)]
pub async fn feed(
ctx: Context<'_>,
#[description = "Item to feed lil buddy"] food: String,
) -> Result<(), Error> {
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
if let Some(mut lil_fren) = lil_fren {
if lil_fren.is_alive() == AliveState::Alive {
let feed: f32 = rand::random_range(-0.1..=1.0);
lil_fren.hunger = (lil_fren.hunger + feed).clamp(-1.0, 1.0);
let guild = ctx.guild_id().unwrap();
let lil_fren_emoji = guild.emoji(&ctx, lil_fren.emoji).await?;
if feed > 0.0 {
ctx.reply("Lil buddy seemed to like that!").await?;
} else {
ctx.reply("Lil buddy DID not like that!").await?;
}
ctx.reply(lil_fren::draw_feed(&lil_fren_emoji, &food))
.await?;
ctx.data().db.insert(lil_fren)?;
} else {
ctx.reply("You may want to check on your buddy...").await?;
}
} else {
ctx.reply("Sorry no little buddy found!").await?;
}
Ok(())
}
/// Give your little buddy the juice of life.
#[poise::command(
prefix_command,
guild_only,
category = "Lil Buddy",
check = "is_not_cancelled"
)]
pub async fn give_water(ctx: Context<'_>) -> Result<(), Error> {
let lil_fren = LilFren::get_lil_fren(&ctx.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 = ctx.guild_id().unwrap();
let lil_fren_emoji = guild.emoji(ctx, lil_fren.emoji).await?;
ctx.reply("Lil buddy be drinking!").await?;
ctx.data().db.insert(lil_fren)?;
let drink = if rand::random_bool(0.20) {
":beer:"
} else {
":cup_with_straw:"
};
ctx.reply(lil_fren::draw_feed(&lil_fren_emoji, drink))
.await?;
} else {
ctx.reply("You may want to check on your buddy...").await?;
}
} else {
ctx.reply("Sorry no little buddy found!").await?;
}
Ok(())
}
/// Play with little buddy before he shreds up the remote again
#[poise::command(
prefix_command,
guild_only,
category = "Lil Buddy",
check = "is_not_cancelled"
)]
pub async fn play(ctx: Context<'_>) -> Result<(), Error> {
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
if let Some(mut lil_fren) = lil_fren {
if lil_fren.is_alive() == AliveState::Alive {
lil_fren.entertainment =
(lil_fren.entertainment + rand::random_range(0.10..1.0)).clamp(-1.0, 1.0);
let guild = ctx.guild_id().unwrap();
let lil_fren_emoji = guild.emoji(ctx, lil_fren.emoji).await?;
ctx.data().db.insert(lil_fren)?;
let toy = ctx.data().cfg.toys.choose(&mut rng()).unwrap();
ctx.reply(lil_fren::draw_feed(&lil_fren_emoji, toy)).await?;
} else {
ctx.reply("You may want to check on your buddy...").await?;
}
} else {
ctx.reply("Sorry no little buddy found!").await?;
}
Ok(())
}
/// Give your little buddy medicine
#[poise::command(
prefix_command,
guild_only,
category = "Lil Buddy",
check = "is_not_cancelled"
)]
pub async fn give_medicine(ctx: Context<'_>) -> Result<(), Error> {
let lil_fren = LilFren::get_lil_fren(&ctx.data().db)?;
if let Some(mut lil_fren) = lil_fren {
if lil_fren.is_alive() == AliveState::Alive {
let guild = ctx.guild_id().unwrap();
let reply = if lil_fren.state == LilFrenState::Sick {
lil_fren.state = LilFrenState::Standing;
"Little buddy feels better now!"
} else {
"Little buddy is now addicted to cough drops, I hope you are happy"
};
let lil_fren_emoji = guild.emoji(ctx, lil_fren.emoji).await?;
ctx.data().db.insert(lil_fren)?;
ctx.reply(reply).await?;
ctx.reply(lil_fren::draw_feed(&lil_fren_emoji, ":pill:"))
.await?;
} else {
ctx.reply("You may want to check on your buddy...").await?;
}
} else {
ctx.reply("Sorry no little buddy found!").await?;
}
Ok(())
}