1
Fork 0
mirror of https://github.com/RYGhub/royalnet.git synced 2024-11-27 13:34:28 +00:00
royalnet/rpgpack/commands/dndroll.py
2020-02-18 14:48:21 +01:00

144 lines
4.7 KiB
Python

import random
import math
from royalnet.commands import *
from ..tables import DndCharacter
from ..utils import get_active_character
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",
"sop": "survival",
}
async def run(self, args: CommandArgs, data: CommandData) -> None:
active_character = await get_active_character(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).")
if second.startswith("a") or second.startswith("v"):
advantage = True
elif second.startswith("d") or second.startswith("d"):
disadvantage = True
else:
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"🎲 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"🎲 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"🎲 1d20{modifier_str} = {roll}{modifier_str} = [b]{total}[/b]")