forked from projectmoon/tenebrous-dicebot
Cthulhu dice only take one amount now
This commit is contained in:
parent
ec66bfa3d6
commit
d67328ac6b
|
@ -1,5 +1,5 @@
|
|||
use crate::context::Context;
|
||||
use crate::dice::calculate_dice_amount;
|
||||
use crate::dice::calculate_single_die_amount;
|
||||
use crate::error::{BotError, DiceRollingError};
|
||||
use crate::parser::Amount;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -8,7 +8,7 @@ use std::fmt;
|
|||
/// A planned dice roll.
|
||||
#[derive(Clone, Debug, PartialEq)]
|
||||
pub struct DiceRoll {
|
||||
pub amounts: Vec<Amount>,
|
||||
pub amount: Amount,
|
||||
pub modifier: DiceRollModifier,
|
||||
}
|
||||
|
||||
|
@ -188,7 +188,7 @@ impl fmt::Display for RolledDice {
|
|||
pub struct AdvancementRoll {
|
||||
/// The amount (0 to 100) of the existing skill. We must beat this
|
||||
/// target number to advance the skill, or roll above a 95.
|
||||
pub existing_skill: Vec<Amount>,
|
||||
pub existing_skill: Amount,
|
||||
}
|
||||
|
||||
impl fmt::Display for AdvancementRoll {
|
||||
|
@ -343,14 +343,14 @@ fn roll_advancement_dice<R: DieRoller>(target: u32, roller: &mut R) -> RolledAdv
|
|||
pub async fn regular_roll(
|
||||
roll_with_ctx: &DiceRollWithContext<'_>,
|
||||
) -> Result<ExecutedDiceRoll, BotError> {
|
||||
let target = calculate_dice_amount(&roll_with_ctx.0.amounts, roll_with_ctx.1).await?;
|
||||
let target = calculate_single_die_amount(&roll_with_ctx.0.amount, roll_with_ctx.1).await?;
|
||||
let target = u32::try_from(target).map_err(|_| DiceRollingError::InvalidAmount)?;
|
||||
|
||||
let mut roller = RngDieRoller(rand::thread_rng());
|
||||
let rolled_dice = roll_regular_dice(&roll_with_ctx.0.modifier, target, &mut roller);
|
||||
|
||||
Ok(ExecutedDiceRoll {
|
||||
target: target,
|
||||
target,
|
||||
modifier: roll_with_ctx.0.modifier,
|
||||
roll: rolled_dice,
|
||||
})
|
||||
|
@ -359,7 +359,9 @@ pub async fn regular_roll(
|
|||
pub async fn advancement_roll(
|
||||
roll_with_ctx: &AdvancementRollWithContext<'_>,
|
||||
) -> Result<ExecutedAdvancementRoll, BotError> {
|
||||
let target = calculate_dice_amount(&roll_with_ctx.0.existing_skill, roll_with_ctx.1).await?;
|
||||
let target =
|
||||
calculate_single_die_amount(&roll_with_ctx.0.existing_skill, roll_with_ctx.1).await?;
|
||||
|
||||
let target = u32::try_from(target).map_err(|_| DiceRollingError::InvalidAmount)?;
|
||||
|
||||
if target > 100 {
|
||||
|
@ -416,10 +418,10 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn regular_roll_rejects_negative_numbers() {
|
||||
let roll = DiceRoll {
|
||||
amounts: vec![Amount {
|
||||
amount: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(-10),
|
||||
}],
|
||||
},
|
||||
modifier: DiceRollModifier::Normal,
|
||||
};
|
||||
|
||||
|
@ -445,10 +447,10 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn advancement_roll_rejects_negative_numbers() {
|
||||
let roll = AdvancementRoll {
|
||||
existing_skill: vec![Amount {
|
||||
existing_skill: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(-10),
|
||||
}],
|
||||
},
|
||||
};
|
||||
|
||||
let db = Database::new_temp().unwrap();
|
||||
|
@ -473,10 +475,10 @@ mod tests {
|
|||
#[tokio::test]
|
||||
async fn advancement_roll_rejects_big_numbers() {
|
||||
let roll = AdvancementRoll {
|
||||
existing_skill: vec![Amount {
|
||||
existing_skill: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(3000),
|
||||
}],
|
||||
},
|
||||
};
|
||||
|
||||
let db = Database::new_temp().unwrap();
|
||||
|
|
|
@ -20,7 +20,6 @@ fn parse_modifier(input: &str) -> Result<DiceRollModifier, DiceParsingError> {
|
|||
//Make diceroll take a vec of Amounts
|
||||
//Split based on :, send first part to parse_modifier.
|
||||
//Send second part to parse_amounts
|
||||
|
||||
pub fn parse_regular_roll(input: &str) -> Result<DiceRoll, DiceParsingError> {
|
||||
let input: Vec<&str> = input.trim().split(":").collect();
|
||||
|
||||
|
@ -31,14 +30,13 @@ pub fn parse_regular_roll(input: &str) -> Result<DiceRoll, DiceParsingError> {
|
|||
}?;
|
||||
|
||||
let modifier = parse_modifier(modifiers_str)?;
|
||||
let amounts = crate::parser::parse_amounts(amounts_str)?;
|
||||
|
||||
Ok(DiceRoll { modifier, amounts })
|
||||
let amount = crate::parser::parse_single_amount(amounts_str)?;
|
||||
Ok(DiceRoll { modifier, amount })
|
||||
}
|
||||
|
||||
pub fn parse_advancement_roll(input: &str) -> Result<AdvancementRoll, DiceParsingError> {
|
||||
let input = input.trim();
|
||||
let amounts = crate::parser::parse_amounts(input)?;
|
||||
let amounts = crate::parser::parse_single_amount(input)?;
|
||||
|
||||
Ok(AdvancementRoll {
|
||||
existing_skill: amounts,
|
||||
|
@ -57,26 +55,32 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
DiceRoll {
|
||||
amounts: vec![Amount {
|
||||
amount: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(60)
|
||||
}],
|
||||
},
|
||||
modifier: DiceRollModifier::Normal
|
||||
},
|
||||
result.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regular_roll_rejects_complex_expressions() {
|
||||
let result = parse_regular_roll("3 + abc + bob - 4");
|
||||
assert!(result.is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regular_roll_accepts_two_bonus() {
|
||||
let result = parse_regular_roll("bb:60");
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
DiceRoll {
|
||||
amounts: vec![Amount {
|
||||
amount: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(60)
|
||||
}],
|
||||
},
|
||||
modifier: DiceRollModifier::TwoBonus
|
||||
},
|
||||
result.unwrap()
|
||||
|
@ -89,10 +93,10 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
DiceRoll {
|
||||
amounts: vec![Amount {
|
||||
amount: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(60)
|
||||
}],
|
||||
},
|
||||
modifier: DiceRollModifier::OneBonus
|
||||
},
|
||||
result.unwrap()
|
||||
|
@ -105,10 +109,10 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
DiceRoll {
|
||||
amounts: vec![Amount {
|
||||
amount: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(60)
|
||||
}],
|
||||
},
|
||||
modifier: DiceRollModifier::TwoPenalty
|
||||
},
|
||||
result.unwrap()
|
||||
|
@ -121,10 +125,10 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
DiceRoll {
|
||||
amounts: vec![Amount {
|
||||
amount: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(60)
|
||||
}],
|
||||
},
|
||||
modifier: DiceRollModifier::OnePenalty
|
||||
},
|
||||
result.unwrap()
|
||||
|
@ -132,7 +136,7 @@ mod tests {
|
|||
}
|
||||
|
||||
#[test]
|
||||
fn regular_roll_accepts_whitespacen() {
|
||||
fn regular_roll_accepts_whitespace() {
|
||||
assert!(parse_regular_roll("60 ").is_ok());
|
||||
assert!(parse_regular_roll(" 60").is_ok());
|
||||
assert!(parse_regular_roll(" 60 ").is_ok());
|
||||
|
@ -167,10 +171,10 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
AdvancementRoll {
|
||||
existing_skill: vec![Amount {
|
||||
existing_skill: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(60)
|
||||
}]
|
||||
}
|
||||
},
|
||||
result.unwrap()
|
||||
);
|
||||
|
@ -187,41 +191,18 @@ mod tests {
|
|||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
AdvancementRoll {
|
||||
existing_skill: vec![Amount {
|
||||
existing_skill: Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Variable(String::from("abc"))
|
||||
}]
|
||||
}
|
||||
},
|
||||
result.unwrap()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn advancement_roll_allows_complex_expressions() {
|
||||
fn advancement_roll_rejects_complex_expressions() {
|
||||
let result = parse_advancement_roll("3 + abc + bob - 4");
|
||||
assert!(result.is_ok());
|
||||
assert_eq!(
|
||||
AdvancementRoll {
|
||||
existing_skill: vec![
|
||||
Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Number(3)
|
||||
},
|
||||
Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Variable(String::from("abc"))
|
||||
},
|
||||
Amount {
|
||||
operator: Operator::Plus,
|
||||
element: Element::Variable(String::from("bob"))
|
||||
},
|
||||
Amount {
|
||||
operator: Operator::Minus,
|
||||
element: Element::Number(4)
|
||||
}
|
||||
]
|
||||
},
|
||||
result.unwrap()
|
||||
);
|
||||
assert!(result.is_err());
|
||||
}
|
||||
}
|
||||
|
|
11
src/dice.rs
11
src/dice.rs
|
@ -5,6 +5,17 @@ use crate::error::DiceRollingError;
|
|||
use crate::parser::Amount;
|
||||
use crate::parser::Element as NewElement;
|
||||
use futures::stream::{self, StreamExt, TryStreamExt};
|
||||
use std::slice;
|
||||
|
||||
/// Calculate the amount of dice to roll by consulting the database
|
||||
/// and replacing variables with corresponding the amount. Errors out
|
||||
/// if it cannot find a variable defined, or if the database errors.
|
||||
pub async fn calculate_single_die_amount(
|
||||
amount: &Amount,
|
||||
ctx: &Context<'_>,
|
||||
) -> Result<i32, BotError> {
|
||||
calculate_dice_amount(slice::from_ref(amount), ctx).await
|
||||
}
|
||||
|
||||
/// Calculate the amount of dice to roll by consulting the database
|
||||
/// and replacing variables with corresponding amounts. Errors out if
|
||||
|
|
|
@ -33,7 +33,7 @@ type ParseResult<T> = Result<T, DiceParsingError>;
|
|||
|
||||
/// A parsed operator for a number. Whether to add or remove it from
|
||||
/// the total amount of dice rolled.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub enum Operator {
|
||||
Plus,
|
||||
Minus,
|
||||
|
|
Loading…
Reference in New Issue