The beginnings of personality in replies.
This commit is contained in:
parent
156c71a0ec
commit
54f0ec1d29
2 changed files with 84 additions and 8 deletions
|
@ -1,4 +1,5 @@
|
||||||
from random import randint
|
import asyncio
|
||||||
|
from random import choice, randint
|
||||||
import re
|
import re
|
||||||
|
|
||||||
import niobot
|
import niobot
|
||||||
|
@ -9,6 +10,17 @@ from niobot import (
|
||||||
NioBot,
|
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):
|
class ChanceModule(Module):
|
||||||
"""Commands that simulate chance (Dice rolls, card selection, etc)."""
|
"""Commands that simulate chance (Dice rolls, card selection, etc)."""
|
||||||
|
@ -19,18 +31,37 @@ class ChanceModule(Module):
|
||||||
@niobot.command()
|
@niobot.command()
|
||||||
async def roll(self, ctx: Context, dice: str):
|
async def roll(self, ctx: Context, dice: str):
|
||||||
"""Roll some dice with an optional modifier."""
|
"""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)
|
valid = re.match(r"(\d+)d(\d+)([\+-/\*]\d+)?", dice)
|
||||||
if valid is None:
|
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.")
|
raise CommandParserError("Invalid dice roll notation.")
|
||||||
dice_parts = (int(valid.group(1)), int(valid.group(2)), valid.group(3))
|
dice_parts = (int(valid.group(1)), int(valid.group(2)), valid.group(3))
|
||||||
|
|
||||||
if not 1 <= dice_parts[0] <= 100:
|
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.")
|
raise CommandParserError("Can only roll between 1 and 100 dice.")
|
||||||
|
|
||||||
if not 2 <= dice_parts[1] <= 100:
|
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.")
|
raise CommandParserError("Dice must have between 2 and 100 faces.")
|
||||||
|
|
||||||
rolls: list[int] = []
|
rolls: list[int] = []
|
||||||
|
@ -38,8 +69,21 @@ class ChanceModule(Module):
|
||||||
rolls.append(randint(1, dice_parts[1]))
|
rolls.append(randint(1, dice_parts[1]))
|
||||||
total = sum(rolls)
|
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(
|
# Give some delay to allow for reading the emote.
|
||||||
# ctx.room, f"{dice_parts[0]}, {dice_parts[1]}, {dice_parts[2]}"
|
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",
|
||||||
|
)
|
||||||
|
|
32
src/tomservobot/stubs.py
Normal file
32
src/tomservobot/stubs.py
Normal file
|
@ -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'<a href="https://matrix.to/#/{user_id}">{short_name}</a>'
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
Loading…
Reference in a new issue