add a !reaction dice roll for a very simple oracle-style vibe check

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
2025-02-24 16:39:06 -06:00
parent 6d8ba18380
commit 3100efd4a9
4 changed files with 121 additions and 2 deletions

View File

@@ -4,10 +4,9 @@ import random
import re
from django.conf import settings
from irc.client import NickMask
from dice.lib import cypher_roll
from dice.lib import cypher_roll, reaction_roll
from dice.roller import DiceRoller
from ircbot.lib import Plugin
@@ -15,6 +14,7 @@ logger = logging.getLogger(__name__)
CYPHER_ROLL_REGEX = r'((?P<type>A|T)(?P<difficulty>\d+))?(?P<mods>(?:\s*(-|\+)\d+)*)\s*(?P<comment>.*)?'
CYPHER_COMMAND_REGEX = r'^!cypher\s+(' + CYPHER_ROLL_REGEX + ')'
REACTION_COMMAND_REGEX = r'^!reaction$'
class Dice(Plugin):
@@ -34,6 +34,8 @@ class Dice(Plugin):
self.handle_roll, -20)
self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], r'^!random\s+(.*)$',
self.handle_random, -20)
self.connection.reactor.add_global_regex_handler(['pubmsg', 'privmsg'], REACTION_COMMAND_REGEX,
self.handle_reaction_roll, -20)
super(Dice, self).start()
@@ -41,6 +43,8 @@ class Dice(Plugin):
"""Tear down handlers."""
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_roll)
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_random)
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_cypher_roll)
self.connection.reactor.remove_global_regex_handler(['pubmsg', 'privmsg'], self.handle_reaction_roll)
super(Dice, self).stop()
@@ -102,6 +106,20 @@ class Dice(Plugin):
reply = "{0:s}".format(choice)
return self.bot.reply(event, reply)
def handle_reaction_roll(self, connection, event, match):
"""Handle the !reaction roll."""
nick = NickMask(event.source).nick
roll, label, summary = reaction_roll()
if summary in ('--', '-'):
result_str = f"4{label}"
elif summary == '~':
result_str = f"9{label}"
else:
result_str = f"9{label}"
return self.bot.reply(event, f"{nick}: the current disposition is: {result_str} 14({roll})")
def handle_roll(self, connection, event, match):
"""Handle the !roll command which covers most common dice stuff."""
nick = NickMask(event.source).nick

View File

@@ -40,3 +40,32 @@ def cypher_roll(difficulty=None, mods=0, is_attack=False):
beats = (roll // 3) - (numexpr.evaluate(mods).item() if mods else 0)
beats = 0 if beats < 0 else beats
return (roll, beats, difficulty <= beats if difficulty else None, effect)
def reaction_roll():
"""Make a reaction roll, which gives some oracle-like randomness to uncertain situations (for solo play or similar).
Returns:
tuple of:
- the result on the d20
- the label for the result
- a summary of the result ('++', '+', '~', '-', '--') (best to worst)
"""
roll = rand.randint(1, 20)
if 1 == roll:
label = 'VERY negative'
summary = '--'
elif 2 <= roll <= 6:
label = 'negative'
summary = '-'
elif 7 <= roll <= 14:
label = 'positive, with complications'
summary = '~'
elif 15 <= roll <= 19:
label = 'positive'
summary = '+'
else:
label = 'VERY positive'
summary = '++'
return (roll, label, summary)