2019-11-11 09:34:05 +00:00
|
|
|
import random
|
2019-12-04 00:47:00 +00:00
|
|
|
import math
|
2019-11-11 09:34:05 +00:00
|
|
|
from royalnet.commands import *
|
2019-12-04 00:47:00 +00:00
|
|
|
from ..tables import DndCharacter
|
2020-02-18 13:48:21 +00:00
|
|
|
from ..utils import get_active_character
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
class DndrollCommand(Command):
|
|
|
|
name: str = "dndroll"
|
|
|
|
|
|
|
|
description: str = "Roll dice as the active DnD character."
|
|
|
|
|
|
|
|
aliases = ["dr", "dndr", "roll", "droll"]
|
|
|
|
|
|
|
|
_skill_names = {
|
|
|
|
"str": "strength",
|
|
|
|
"for": "strength",
|
|
|
|
"dex": "dexterity",
|
|
|
|
"des": "dexterity",
|
|
|
|
"con": "constitution",
|
|
|
|
"cos": "constitution",
|
|
|
|
"inte": "intelligence",
|
|
|
|
"wis": "wisdom",
|
|
|
|
"sag": "wisdom",
|
|
|
|
"cha": "charisma",
|
|
|
|
"car": "charisma",
|
|
|
|
|
|
|
|
"ststr": "strength_save",
|
|
|
|
"stfor": "strength_save",
|
|
|
|
"stdex": "dexterity_save",
|
|
|
|
"stdes": "dexterity_save",
|
|
|
|
"stcon": "constitution_save",
|
|
|
|
"stcos": "constitution_save",
|
|
|
|
"stint": "intelligence_save",
|
|
|
|
"stwis": "wisdom_save",
|
|
|
|
"stsag": "wisdom_save",
|
|
|
|
"stcha": "charisma_save",
|
|
|
|
"stcar": "charisma_save",
|
|
|
|
|
|
|
|
"tsstr": "strength_save",
|
|
|
|
"tsfor": "strength_save",
|
|
|
|
"tsdex": "dexterity_save",
|
|
|
|
"tsdes": "dexterity_save",
|
|
|
|
"tscon": "constitution_save",
|
|
|
|
"tscos": "constitution_save",
|
|
|
|
"tsint": "intelligence_save",
|
|
|
|
"tswis": "wisdom_save",
|
|
|
|
"tssag": "wisdom_save",
|
|
|
|
"tscha": "charisma_save",
|
|
|
|
"tscar": "charisma_save",
|
|
|
|
|
|
|
|
"acr": "acrobatics",
|
|
|
|
"add": "animal_handling",
|
|
|
|
"ani": "animal_handling",
|
|
|
|
"arc": "arcana",
|
|
|
|
"ath": "athletics",
|
|
|
|
"dec": "deception",
|
|
|
|
"ing": "deception",
|
|
|
|
"his": "history",
|
|
|
|
"sto": "history",
|
|
|
|
"ins": "insight",
|
|
|
|
"intu": "insight",
|
|
|
|
"inti": "intimidation",
|
|
|
|
"inv": "investigation",
|
|
|
|
"med": "medicine",
|
|
|
|
"nat": "nature",
|
|
|
|
"perc": "perception",
|
|
|
|
"perf": "performance",
|
|
|
|
"pers": "persuasion",
|
|
|
|
"rel": "religion",
|
|
|
|
"sle": "sleight_of_hand",
|
|
|
|
"soh": "sleight_of_hand",
|
|
|
|
"rap": "sleight_of_hand",
|
|
|
|
"ste": "stealth",
|
|
|
|
"nas": "stealth",
|
|
|
|
"sur": "survival",
|
2020-02-18 13:48:21 +00:00
|
|
|
"sop": "survival",
|
2019-11-11 09:34:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
2020-09-16 00:37:31 +00:00
|
|
|
async with data.session_acm() as session:
|
|
|
|
active_character = await get_active_character(session=session, data=data)
|
|
|
|
if active_character is None:
|
|
|
|
raise CommandError("You don't have an active character.")
|
|
|
|
char = active_character.character
|
|
|
|
|
|
|
|
first = args[0]
|
|
|
|
second = args.optional(1)
|
|
|
|
third = args.optional(2)
|
|
|
|
|
|
|
|
advantage = False
|
|
|
|
disadvantage = False
|
|
|
|
extra_modifier = 0
|
|
|
|
|
|
|
|
if third:
|
|
|
|
try:
|
|
|
|
extra_modifier = int(third)
|
|
|
|
except ValueError:
|
|
|
|
raise InvalidInputError("Invalid modifier value (third parameter).")
|
2019-11-11 09:34:05 +00:00
|
|
|
if second.startswith("a") or second.startswith("v"):
|
|
|
|
advantage = True
|
|
|
|
elif second.startswith("d") or second.startswith("d"):
|
|
|
|
disadvantage = True
|
|
|
|
else:
|
2020-09-16 00:37:31 +00:00
|
|
|
raise InvalidInputError("Invalid advantage string (second parameter).")
|
|
|
|
|
|
|
|
elif second:
|
|
|
|
try:
|
|
|
|
extra_modifier = int(second)
|
|
|
|
except ValueError:
|
|
|
|
if second.startswith("a") or second.startswith("v"):
|
|
|
|
advantage = True
|
|
|
|
elif second.startswith("d") or second.startswith("d"):
|
|
|
|
disadvantage = True
|
|
|
|
else:
|
|
|
|
raise InvalidInputError("Invalid modifier value or advantage string (second parameter).")
|
|
|
|
|
|
|
|
skill_short_name = first.lower()
|
|
|
|
for root in self._skill_names:
|
|
|
|
if skill_short_name.startswith(root):
|
|
|
|
skill_name = self._skill_names[root]
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
raise CommandError("Invalid skill name (first parameter).")
|
|
|
|
|
|
|
|
skill_modifier = int(char.__getattribute__(skill_name))
|
|
|
|
modifier = skill_modifier + extra_modifier
|
|
|
|
modifier_str = f"{modifier:+d}" if modifier != 0 else ""
|
|
|
|
|
|
|
|
if advantage:
|
|
|
|
roll_a = random.randrange(1, 21)
|
|
|
|
roll_b = random.randrange(1, 21)
|
|
|
|
roll = max([roll_a, roll_b])
|
|
|
|
total = roll + modifier
|
|
|
|
await data.reply(f"🎲 [i]{skill_name.capitalize()}[/i]: 2d20h1{modifier_str} = ({roll_a}|{roll_b} ){modifier_str} = [b]{total}[/b]")
|
|
|
|
elif disadvantage:
|
|
|
|
roll_a = random.randrange(1, 21)
|
|
|
|
roll_b = random.randrange(1, 21)
|
|
|
|
roll = min([roll_a, roll_b])
|
|
|
|
total = roll + modifier
|
|
|
|
await data.reply(f"🎲 [i]{skill_name.capitalize()}[/i]: 2d20l1{modifier_str} = ({roll_a}|{roll_b}){modifier_str} = [b]{total}[/b]")
|
|
|
|
else:
|
|
|
|
roll = random.randrange(1, 21)
|
|
|
|
total = roll + modifier
|
|
|
|
await data.reply(f"🎲 [i]{skill_name.capitalize()}[/i]: 1d20{modifier_str} = {roll}{modifier_str} = [b]{total}[/b]")
|