diff --git a/src/tomservobot/chance.py b/src/tomservobot/chance.py index 5f7f640..7059f67 100644 --- a/src/tomservobot/chance.py +++ b/src/tomservobot/chance.py @@ -1,4 +1,5 @@ -from random import randint +import asyncio +from random import choice, randint import re import niobot @@ -9,6 +10,17 @@ from niobot import ( NioBot, ) +from .stubs import ERROR_STARTS, get_random_stub, format_mention + + +_DICE_LOCATIONS = [ + "pulls some dice seemingly from thin air.", + "extracts some dice from his mouth.", + "spins around and a number of dice appear in his hands.", + "opens the closest drawer and takes out a container of random dice.", + "powers on a tablet and executes a dice-rolling application.", +] + class ChanceModule(Module): """Commands that simulate chance (Dice rolls, card selection, etc).""" @@ -19,18 +31,37 @@ class ChanceModule(Module): @niobot.command() async def roll(self, ctx: Context, dice: str): """Roll some dice with an optional modifier.""" + err_prelude = get_random_stub(ERROR_STARTS, ctx.message.sender) valid = re.match(r"(\d+)d(\d+)([\+-/\*]\d+)?", dice) if valid is None: - await ctx.respond("Error: Invalid dice roll notation.") + await ctx.client.send_message( + ctx.room, + f"{err_prelude}that's an invalid dice roll.", + reply_to=ctx.message, + message_type="m.text", + content_type="html", + ) raise CommandParserError("Invalid dice roll notation.") dice_parts = (int(valid.group(1)), int(valid.group(2)), valid.group(3)) if not 1 <= dice_parts[0] <= 100: - await ctx.respond("Error: Can only roll between 1 and 100 dice.") + await ctx.client.send_message( + ctx.room, + f"{err_prelude}I can only roll between 1 and 100 dice.", + reply_to=ctx.message, + message_type="m.text", + content_type="html", + ) raise CommandParserError("Can only roll between 1 and 100 dice.") if not 2 <= dice_parts[1] <= 100: - await ctx.respond("Error: Dice must have between 2 and 100 faces.") + await ctx.client.send_message( + ctx.room, + f"{err_prelude}the dice can only have between 2 and 100 faces.", + reply_to=ctx.message, + message_type="m.text", + content_type="html", + ) raise CommandParserError("Dice must have between 2 and 100 faces.") rolls: list[int] = [] @@ -38,8 +69,21 @@ class ChanceModule(Module): rolls.append(randint(1, dice_parts[1])) total = sum(rolls) - await ctx.respond(f"{dice}: {total} ({rolls})") + await ctx.client.send_message( + ctx.room, + choice(_DICE_LOCATIONS), + message_type="m.emote", + content_type="html", + ) - # await ctx.client.send_message( - # ctx.room, f"{dice_parts[0]}, {dice_parts[1]}, {dice_parts[2]}" - # ) + # Give some delay to allow for reading the emote. + await asyncio.sleep(1) + + html_sender = format_mention(ctx.message.sender) + await ctx.client.send_message( + ctx.room, + f"{html_sender}: {dice} = {total} ({rolls})", + reply_to=ctx.message, + message_type="m.text", + content_type="html", + ) diff --git a/src/tomservobot/stubs.py b/src/tomservobot/stubs.py new file mode 100644 index 0000000..6f18fc4 --- /dev/null +++ b/src/tomservobot/stubs.py @@ -0,0 +1,32 @@ +from random import choice + + +ERROR_STARTS: list[str] = [ + "Hey pal, ", + "Hey {sender}, ", + "Uhhhhh, ", + "Uhhhhh, {sender} ", + "Nothing doing--", + "Yeahhh, about that--", + "Yo {sender}, ", + "Look here bub, ", + "Look here {sender}, ", +] + + +def format_mention(user_id: str) -> str: + """Creates an HTML stub for beautifying a mention in a message.""" + short_name = user_id.split(":")[0][1:] + return f'{short_name}' + + +def format_sender(stub: str, sender: str) -> str: + """Adds the sender's name to the format string in a stub.""" + if "{sender}" in stub: + return stub.replace("{sender}", format_mention(sender)) + return stub + + +def get_random_stub(stub_list: list[str], sender: str) -> str: + """Picks a random stub from a list of your choosing.""" + return format_sender(choice(stub_list), sender)