added different format for high repeat counts
This commit is contained in:
parent
3db5d719d2
commit
0843c77473
2 changed files with 53 additions and 44 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
pub const MAX_DICE_COUNT_PER_ROLL: usize = 20_000;
|
pub const MAX_DICE_COUNT_PER_ROLL: usize = 20_000;
|
||||||
pub const RESULT_CULL_CHARACTER_THRESHOLD: usize = 3000;
|
pub const RESULT_CULL_CHARACTER_THRESHOLD: usize = 3000;
|
||||||
pub const MAX_DISPLAYED_DICE_PER_MESSAGE: usize = 100;
|
pub const MAX_DISPLAYED_DICE_PER_MESSAGE: usize = 100;
|
||||||
pub const MAX_ROLL_REPEATS: usize = 35;
|
pub const MAX_ROLL_REPEATS: usize = 100;
|
||||||
95
src/main.rs
95
src/main.rs
|
|
@ -1,3 +1,4 @@
|
||||||
|
use std::fmt::Write as FmtWrite;
|
||||||
mod dice;
|
mod dice;
|
||||||
mod limits;
|
mod limits;
|
||||||
mod parsing;
|
mod parsing;
|
||||||
|
|
@ -12,7 +13,8 @@ use serenity::all::{
|
||||||
FullEvent, Interaction, InteractionContext, MessageFlags, ResolvedOption, ResolvedValue,
|
FullEvent, Interaction, InteractionContext, MessageFlags, ResolvedOption, ResolvedValue,
|
||||||
};
|
};
|
||||||
use serenity::builder::{
|
use serenity::builder::{
|
||||||
CreateCommand, CreateContainer, CreateContainerComponent, CreateInteractionResponse, CreateInteractionResponseMessage, CreateTextDisplay,
|
CreateCommand, CreateContainer, CreateContainerComponent, CreateInteractionResponse,
|
||||||
|
CreateInteractionResponseMessage, CreateTextDisplay,
|
||||||
};
|
};
|
||||||
use serenity::{async_trait, prelude::*};
|
use serenity::{async_trait, prelude::*};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
@ -135,7 +137,8 @@ pub async fn roll(ctx: &Context, command: &CommandInteraction) -> anyhow::Result
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.unwrap_or(1)
|
.unwrap_or(1)
|
||||||
.min(MAX_ROLL_REPEATS as i64);
|
.min(MAX_ROLL_REPEATS as i64)
|
||||||
|
.max(1) as usize;
|
||||||
let private = options
|
let private = options
|
||||||
.iter()
|
.iter()
|
||||||
.find(|option| option.name == "private")
|
.find(|option| option.name == "private")
|
||||||
|
|
@ -177,46 +180,59 @@ pub async fn roll(ctx: &Context, command: &CommandInteraction) -> anyhow::Result
|
||||||
let average = expression.average(&mut rng)?;
|
let average = expression.average(&mut rng)?;
|
||||||
let ev = (average * 10.0).round() / 10.0;
|
let ev = (average * 10.0).round() / 10.0;
|
||||||
|
|
||||||
let discord_md = Arc::new(std::sync::RwLock::new(DiscordMd {
|
let mut pre_paragraphs = Vec::new();
|
||||||
buffers: vec![],
|
|
||||||
dice_written: 0,
|
|
||||||
}));
|
|
||||||
if let Some(description) = description {
|
if let Some(description) = description {
|
||||||
discord_md
|
pre_paragraphs.insert(0, format!(">>> {description}\n"));
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.buffers
|
|
||||||
.push(format!(">>> {description}\n"));
|
|
||||||
}
|
|
||||||
for _ in 0..repeat {
|
|
||||||
let mut witness = DiscordMd::create_witness(&discord_md);
|
|
||||||
let result = expression.evaluate(&mut rng, &mut witness, i64::MAX)?;
|
|
||||||
witness.witness_total_result(result)?;
|
|
||||||
witness.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut post_paragraphs = Vec::new();
|
||||||
if fixed_seed.is_some() {
|
if fixed_seed.is_some() {
|
||||||
discord_md
|
post_paragraphs.push("***⚠️ This is not a fair roll. The result was generated based on a fixed seed and is thus fully reproducible.***".to_string());
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.buffers
|
|
||||||
.push("***⚠️ This is not a fair roll. The result was generated based on a fixed seed and is thus fully reproducible.***".to_string());
|
|
||||||
}
|
}
|
||||||
discord_md
|
post_paragraphs.push(format!("-# Expected value: {ev} | Seed: {seed}"));
|
||||||
.write()
|
|
||||||
.unwrap()
|
|
||||||
.buffers
|
|
||||||
.push(format!("-# Expected value: {ev} | Seed: {seed}"));
|
|
||||||
|
|
||||||
let discord_md = Arc::into_inner(discord_md)
|
let surrounding_par_count = pre_paragraphs.len() + post_paragraphs.len();
|
||||||
.unwrap()
|
|
||||||
.into_inner()?;
|
|
||||||
|
|
||||||
if discord_md.character_count() > 4000 {
|
let paragraphs = if repeat <= 40 - surrounding_par_count {
|
||||||
|
let discord_md = Arc::new(std::sync::RwLock::new(DiscordMd {
|
||||||
|
buffers: Vec::with_capacity(repeat),
|
||||||
|
dice_written: 0,
|
||||||
|
}));
|
||||||
|
for _ in 0..repeat {
|
||||||
|
let mut witness = DiscordMd::create_witness(&discord_md);
|
||||||
|
let result = expression.evaluate(&mut rng, &mut witness, i64::MAX)?;
|
||||||
|
witness.witness_total_result(result)?;
|
||||||
|
witness.end();
|
||||||
|
}
|
||||||
|
let discord_md = Arc::into_inner(discord_md).unwrap().into_inner()?;
|
||||||
|
|
||||||
|
discord_md.buffers
|
||||||
|
} else {
|
||||||
|
let mut par = String::new();
|
||||||
|
for i in 0..repeat {
|
||||||
|
if i > 0 {
|
||||||
|
write!(par, ", ")?;
|
||||||
|
}
|
||||||
|
write!(
|
||||||
|
par,
|
||||||
|
"**{}**",
|
||||||
|
expression.evaluate(&mut rng, &mut std::io::sink(), i64::MAX)?
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
vec![par]
|
||||||
|
};
|
||||||
|
|
||||||
|
pre_paragraphs.extend(paragraphs);
|
||||||
|
pre_paragraphs.extend(post_paragraphs);
|
||||||
|
let paragraphs = pre_paragraphs;
|
||||||
|
|
||||||
|
if paragraphs.iter().map(|s| s.chars().count()).sum::<usize>() > 4000
|
||||||
|
|| paragraphs.len() > 40
|
||||||
|
{
|
||||||
bail!("Resulting message was too long, please roll fewer dice!");
|
bail!("Resulting message was too long, please roll fewer dice!");
|
||||||
}
|
};
|
||||||
|
|
||||||
let text_components = discord_md
|
let text_components = paragraphs
|
||||||
.buffers
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|text| CreateContainerComponent::TextDisplay(CreateTextDisplay::new(text)))
|
.map(|text| CreateContainerComponent::TextDisplay(CreateTextDisplay::new(text)))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
@ -227,20 +243,13 @@ pub async fn roll(ctx: &Context, command: &CommandInteraction) -> anyhow::Result
|
||||||
text_components,
|
text_components,
|
||||||
))])
|
))])
|
||||||
// flags needs to be called before ephemeral for correct ordering
|
// flags needs to be called before ephemeral for correct ordering
|
||||||
.flags(
|
.flags(MessageFlags::IS_COMPONENTS_V2 | MessageFlags::SUPPRESS_NOTIFICATIONS)
|
||||||
MessageFlags::IS_COMPONENTS_V2 | MessageFlags::SUPPRESS_NOTIFICATIONS,
|
|
||||||
)
|
|
||||||
.ephemeral(private),
|
.ephemeral(private),
|
||||||
);
|
);
|
||||||
|
|
||||||
debug!("Returning response: {response:#?}");
|
debug!("Returning response: {response:#?}");
|
||||||
|
|
||||||
command
|
command.create_response(&ctx.http, response).await?;
|
||||||
.create_response(
|
|
||||||
&ctx.http,
|
|
||||||
response,
|
|
||||||
)
|
|
||||||
.await?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue