diff --git a/src/cmds/wwrps.rs b/src/cmds/wwrps.rs new file mode 100644 index 0000000..6f5ad52 --- /dev/null +++ b/src/cmds/wwrps.rs @@ -0,0 +1,105 @@ +use poise::serenity_prelude::User; + +use crate::{Context, Error, data::get_mutex_data, lang, messages::send_msg}; + + +#[derive(poise::ChoiceParameter, PartialEq, Clone)] +#[repr(u8)] +pub enum RPS { + Paper = 0, + Rock = 1, + Scissors = 2 +} + + +#[derive(Clone)] +pub struct RPSPlayer { + pub selection: RPS, + pub user: User, + pub anonymous: bool +} +pub struct RPSGame { + pub players: [Option; 2], +} + + +impl RPSGame { + pub fn new() -> Self { + return RPSGame { + players: [None, None], + } + } + + pub fn add_player(&mut self, player: RPSPlayer) -> Result<(), Error> { + if let Some(p1) = &self.players[0] + { if p1.user == player.user { return Err(Error::from("Cannot add player, it already exists!")); }} + + if self.players[0].is_none() { self.players[0] = Some(player); return Ok(()); } + else if self.players[1].is_none() { self.players[1] = Some(player); return Ok(()); } + else { return Err(Error::from("Cannot add player, list is full!")); } + } + + pub fn clear(&mut self) + { self.players = [None, None]; } + + + pub fn get_winner(&self) -> Option { + if self.players.iter().any(|i| i.is_none()) + { return None; } + + let Some(p1) = self.players[0].clone() else { return None; }; + let Some(p2) = self.players[1].clone() else { return None; }; + + let i1 = p1.selection as u8; + let i2 = p2.selection as u8; + + if i1 == i2 { return None; } + else if (i1 + 1) % 3 == i2 { return Some(0); } + else { return Some(1); } + } + + pub fn is_full_lobby(&self) -> bool + { return self.players.iter().all(|i| i.is_some()); } +} + + +#[poise::command( + slash_command, + prefix_command, + category = "fun", + rename = "wwrps", + required_bot_permissions = "SEND_MESSAGES | VIEW_CHANNEL" +)] +/// World-Wide Rock Paper Scissors. Play with a completely random person! +pub async fn cmd( + ctx: Context<'_>, + selection: RPS, + #[description = "If true, replaces your username with [Anonymous]."] anonymous: bool +) -> Result<(), Error> +{ + let c_o = get_wwrps_channel(ctx).await; + + if c_o.is_none() { send_msg(ctx, lang!("dc_msg_wwrps_not_in_data"), true, true).await; return Ok(()); } + let c = c_o.unwrap(); + + let mut game = &ctx.data().rps_game; + + if !game.is_full_lobby() { game.add_player(RPSPlayer { selection, user: ctx.author().clone(), anonymous }); } + + return Ok(()); +} + + +async fn get_wwrps_channel(ctx: Context<'_>) -> Option { + let d = get_mutex_data(&ctx.data().discord_data).await.unwrap(); + + let is_guild = ctx.guild_channel().await.is_some(); + + if !is_guild { return Some(ctx.channel_id().get()); } + + let Some(servers) = d.get("servers") else { return None; }; + let Some(s) = servers.get(ctx.guild_id().unwrap().get() as usize) else { return None; }; + let Some(c_id) = s.get("wwrps_channel") else { return None; }; + + return Some(c_id.as_u64().unwrap()); +} \ No newline at end of file diff --git a/src/data.rs b/src/data.rs index 0d5f95f..67f43b2 100644 --- a/src/data.rs +++ b/src/data.rs @@ -155,7 +155,7 @@ pub async fn dc_add_server(data: &Data, server_id: u64) -> Result<(), ()> { let servers = dc_data["servers"].as_object_mut().unwrap(); if !servers.contains_key(&server_id.to_string()) { - servers.insert(server_id.to_string(), json!({ DC_POSTS_CHANNEL_KEY: 0 })); + servers.insert(server_id.to_string(), json!({})); } return Ok(()); diff --git a/src/gen.rs b/src/gen.rs index a9315e2..4cff2c1 100644 --- a/src/gen.rs +++ b/src/gen.rs @@ -5,6 +5,7 @@ use poise::serenity_prelude as serenity; use poise::serenity_prelude::Client; use toml::Value; +use crate::cmds::wwrps::RPSGame; use crate::data::get_toml_mutex; use crate::{Args, Cmd, Data, cmds, data, db_cmds, debug_cmds, events, re_cmds, rs_println}; @@ -26,6 +27,7 @@ pub async fn gen_data(args: Args, owners: Vec) -> Data { let data = Data { owners, ball_prompts: [ball_classic, ball_quirk], + rps_game: RPSGame::new(), bk_mods: mods_vec_u64, reddit_data: None.into(), discord_data: None.into(), diff --git a/src/main.rs b/src/main.rs index d4b435e..d119a04 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,6 +7,7 @@ mod cmds { pub mod embed; pub mod help; pub mod send; + pub mod wwrps; } mod re_cmds { pub mod add; @@ -62,6 +63,7 @@ use tokio::runtime::Runtime; use tokio::sync::Mutex; use websocket::send_cmd_json; +use crate::cmds::wwrps::RPSGame; use crate::data::get_toml_mutex; use crate::schedule::Schedule; @@ -95,6 +97,7 @@ type Cmd = Command>; struct Data { owners: Vec, ball_prompts: [Vec; 2], + rps_game: RPSGame, reddit_data: Mutex>, discord_data: Mutex>, cfg: Mutex>,