pretty format discord message
This commit is contained in:
parent
739316f903
commit
d0ee7a5e3e
7 changed files with 78 additions and 11 deletions
|
@ -1,14 +1,32 @@
|
|||
import typing
|
||||
from datetime import datetime
|
||||
|
||||
import disnake
|
||||
from disnake.ext import commands
|
||||
|
||||
from src.dice.dice import DiceRoller
|
||||
from src.dice.dice import DiceRoller, DieExpressionResult
|
||||
|
||||
|
||||
class DiceCog(commands.Cog):
|
||||
def __init__(self, bot):
|
||||
self.bot = bot
|
||||
|
||||
@staticmethod
|
||||
def format_die_result_to_fields(
|
||||
die_result: DieExpressionResult,
|
||||
) -> list[typing.Tuple[str, str]]:
|
||||
roll_fields = []
|
||||
for index, die in enumerate(die_result.dies):
|
||||
roll_fields.append(
|
||||
(
|
||||
f"- #{index+1} 🎲 ",
|
||||
f"Res: {die.result}, Mod: {die.modifier}, Rolls: {die.rolls}",
|
||||
)
|
||||
)
|
||||
return roll_fields
|
||||
|
||||
@commands.command(name="roll", aliases=["r"])
|
||||
async def roll(self, ctx, dice_expression: str):
|
||||
async def roll(self, ctx, _dice_expression: str):
|
||||
"""
|
||||
A die can be rolled using the following expression:
|
||||
- 1d20 will roll a 20-faceted die and output the result a random number between 1 and 20.
|
||||
|
@ -16,13 +34,30 @@ class DiceCog(commands.Cog):
|
|||
- 2d20 will roll a two d20 dies and multiply the result by two.
|
||||
- 2d20+5 will roll a two d20 dies and multiply the result by two and ads 5.
|
||||
"""
|
||||
try:
|
||||
message: str = ctx.message.clean_content
|
||||
dice_expression = message.split(" ", 1)[1]
|
||||
if dice_expression == "":
|
||||
return
|
||||
if dice_expression == "0/0": # easter eggs
|
||||
return await ctx.send("What do you expect me to do, destroy the universe?")
|
||||
return await ctx.send(
|
||||
"What do you expect me to do, destroy the universe?"
|
||||
)
|
||||
|
||||
try:
|
||||
roll_result = DiceRoller.roll_simple(dice_expression)
|
||||
await ctx.send(f"You rolled: {roll_result}")
|
||||
die_result: DieExpressionResult = DiceRoller.roll(dice_expression)
|
||||
|
||||
embed = disnake.Embed(
|
||||
title="",
|
||||
description=f"{dice_expression} = {die_result.total}",
|
||||
timestamp=datetime.now(),
|
||||
)
|
||||
embed_fields = self.format_die_result_to_fields(die_result)
|
||||
for title, value in embed_fields:
|
||||
embed.add_field(title, value, inline=False)
|
||||
|
||||
await ctx.send(
|
||||
f"The mighty **{ctx.author.name}** has rolled the dice for a total of **{die_result.total}**!",
|
||||
embed=embed,
|
||||
)
|
||||
except ValueError as e:
|
||||
await ctx.send(f"Roll failed: {e}")
|
||||
|
|
|
@ -57,4 +57,15 @@ class DiceRoller:
|
|||
:return: The die result.
|
||||
"""
|
||||
result = DiceRoller._parser.parse(expression)
|
||||
return DieExpressionResult(**result)
|
||||
|
||||
dies = []
|
||||
for die in result.get("dies", []):
|
||||
dies.append(
|
||||
DieRollResult(
|
||||
modifier=die.get("modifier", 0),
|
||||
result=die.get("result"),
|
||||
rolls=die.get("rolls"),
|
||||
type=die.get("type"),
|
||||
)
|
||||
)
|
||||
return DieExpressionResult(total=result.get("total"), dies=dies)
|
||||
|
|
|
@ -15,7 +15,10 @@ class DieSemantics:
|
|||
return {"total": die.get("result"), "dies": [die]}
|
||||
elif isinstance(die, list):
|
||||
return_value = {"total": 0, "dies": copy.deepcopy(die)}
|
||||
operators = deque(ast.get("op", []))
|
||||
operators = ast.get("op", [])
|
||||
if not isinstance(operators, list):
|
||||
operators = [operators]
|
||||
operators = deque(operators)
|
||||
|
||||
die_results = deque(map(lambda x: x.get("result"), die))
|
||||
# Note: we may need to use a dequeue, the ops are quite inefficient.
|
||||
|
|
0
tests/bot/__init__.py
Normal file
0
tests/bot/__init__.py
Normal file
0
tests/bot/discord/__init__.py
Normal file
0
tests/bot/discord/__init__.py
Normal file
0
tests/bot/discord/commands/__init__.py
Normal file
0
tests/bot/discord/commands/__init__.py
Normal file
18
tests/bot/discord/commands/test_dice.py
Normal file
18
tests/bot/discord/commands/test_dice.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
from src.bot.discord.commands.dice import DiceCog
|
||||
from src.dice.dice import DieExpressionResult, DieRollResult
|
||||
|
||||
|
||||
def test_format_die_result_to_message():
|
||||
message = DiceCog.format_die_result_to_fields(
|
||||
DieExpressionResult(
|
||||
total=25,
|
||||
dies=[
|
||||
DieRollResult(result=10, modifier=5, rolls=[10], type="d"),
|
||||
DieRollResult(result=15, modifier=0, rolls=[10, 5], type="d"),
|
||||
],
|
||||
),
|
||||
)
|
||||
assert message == [
|
||||
("- #1 🎲 ", "Res: 10, Mod: 5, Rolls: [10]"),
|
||||
("- #2 🎲 ", "Res: 15, Mod: 0, Rolls: [10, 5]"),
|
||||
]
|
Loading…
Reference in a new issue