mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-27 13:34:28 +00:00
Change dnd commands
This commit is contained in:
parent
d67110be09
commit
50700c7b63
9 changed files with 325 additions and 282 deletions
|
@ -5,9 +5,6 @@ from .dndactive import DndactiveCommand
|
|||
from .dndinfo import DndinfoCommand
|
||||
from .dndnew import DndnewCommand
|
||||
from .dndedit import DndeditCommand
|
||||
from .dndroll import DndrollCommand
|
||||
from .dndrolladv import DndrolladvCommand
|
||||
from .dndrolldis import DndrolldisCommand
|
||||
|
||||
# Enter the commands of your Pack here!
|
||||
available_commands = [
|
||||
|
@ -17,9 +14,6 @@ available_commands = [
|
|||
DndinfoCommand,
|
||||
DndnewCommand,
|
||||
DndeditCommand,
|
||||
DndrollCommand,
|
||||
DndrolladvCommand,
|
||||
DndrolldisCommand,
|
||||
]
|
||||
|
||||
# Don't change this, it should automatically generate __all__
|
||||
|
|
|
@ -1,60 +1,35 @@
|
|||
import re
|
||||
from royalnet.commands import *
|
||||
from .dndnew import DndnewCommand
|
||||
from ..tables import DndCharacter, DndActiveCharacter
|
||||
|
||||
|
||||
class DndeditCommand(Command):
|
||||
class DndeditCommand(DndnewCommand):
|
||||
name: str = "dndedit"
|
||||
|
||||
description: str = "Edit the active DnD character."
|
||||
|
||||
aliases = ["de", "dnde", "edit", "dedit"]
|
||||
|
||||
syntax = "{name}\n" \
|
||||
"LV {level}\n" \
|
||||
"\n" \
|
||||
"STR {strength}\n" \
|
||||
"DEX {dexterity}\n" \
|
||||
"CON {constitution}\n" \
|
||||
"INT {intelligence}\n" \
|
||||
"WIS {wisdom}\n" \
|
||||
"CHA {charisma}\n" \
|
||||
"\n" \
|
||||
"MAXHP {max_hp}\n" \
|
||||
"AC {armor_class}"
|
||||
|
||||
tables = {DndCharacter, DndActiveCharacter}
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
name, level, strength, dexterity, constitution, intelligence, wisdom, charisma, max_hp, armor_class = \
|
||||
args.match(r"([\w ]+\w)\s*"
|
||||
r"LV\s+(\d+)\s+"
|
||||
r"STR\s+(\d+)\s+"
|
||||
r"DEX\s+(\d+)\s+"
|
||||
r"CON\s+(\d+)\s+"
|
||||
r"INT\s+(\d+)\s+"
|
||||
r"WIS\s+(\d+)\s+"
|
||||
r"CHA\s+(\d+)\s+"
|
||||
r"MAXHP\s+(\d+)\s+"
|
||||
r"AC\s+(\d+)", re.IGNORECASE)
|
||||
try:
|
||||
int(name)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
raise CommandError("Character names cannot be composed of only a number.")
|
||||
character_sheet = args.joined()
|
||||
|
||||
if character_sheet == "":
|
||||
await data.reply(self._syntax())
|
||||
return
|
||||
|
||||
author = await data.get_author(error_if_none=True)
|
||||
char = author.dnd_active_character.character
|
||||
char.name = name
|
||||
char.level = level
|
||||
char.strength = strength
|
||||
char.dexterity = dexterity
|
||||
char.constitution = constitution
|
||||
char.intelligence = intelligence
|
||||
char.wisdom = wisdom
|
||||
char.charisma = charisma
|
||||
char.max_hp = max_hp
|
||||
char.armor_class = armor_class
|
||||
data.session.add(char)
|
||||
if author.dnd_active_character is None:
|
||||
raise CommandError("You don't have an active character.")
|
||||
|
||||
char: DndCharacter = author.dnd_active_character.character
|
||||
|
||||
arguments = self._parse(character_sheet)
|
||||
for key in arguments:
|
||||
char.__setattr__(key, arguments[key])
|
||||
|
||||
await data.session_commit()
|
||||
|
||||
await data.reply(f"✅ Edit successful!")
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import re
|
||||
# noinspection PyUnresolvedReferences
|
||||
from royalnet.commands import *
|
||||
from ..tables import DndCharacter
|
||||
from ..utils import DndProficiencyType
|
||||
|
||||
|
||||
class DndnewCommand(Command):
|
||||
|
@ -10,51 +12,59 @@ class DndnewCommand(Command):
|
|||
|
||||
aliases = ["dn", "dndn", "new", "dnew"]
|
||||
|
||||
syntax = "{name}\n" \
|
||||
"LV {level}\n" \
|
||||
"\n" \
|
||||
"STR {strength}\n" \
|
||||
"DEX {dexterity}\n" \
|
||||
"CON {constitution}\n" \
|
||||
"INT {intelligence}\n" \
|
||||
"WIS {wisdom}\n" \
|
||||
"CHA {charisma}\n" \
|
||||
"\n" \
|
||||
"MAXHP {max_hp}\n" \
|
||||
"AC {armor_class}"
|
||||
syntax = "{name}\n{character_sheet}"
|
||||
|
||||
tables = {DndCharacter}
|
||||
|
||||
def _search_value(self, name: str, string: str):
|
||||
return re.search(r"\s*" + name + r"\s*([0-9]+)\s*", string, re.IGNORECASE)
|
||||
|
||||
def _parse(self, character_sheet: str) -> dict:
|
||||
columns = list(self.alchemy.DndCharacter.__table__.columns)
|
||||
column_names = [column.name for column in columns if (not column.primary_key and
|
||||
not column.foreign_keys and
|
||||
column.name != "name")]
|
||||
arguments = {}
|
||||
for column_name in column_names:
|
||||
match = self._search_value(column_name, character_sheet)
|
||||
if match:
|
||||
if column_name.endswith("_proficiency"):
|
||||
arguments[column_name] = DndProficiencyType(float(match.group(1)))
|
||||
else:
|
||||
arguments[column_name] = match.group(1)
|
||||
return arguments
|
||||
|
||||
def _syntax(self) -> str:
|
||||
columns = list(self.alchemy.DndCharacter.__table__.columns)
|
||||
column_names = [column.name for column in columns if (not column.primary_key and
|
||||
not column.foreign_keys and
|
||||
column.name != "name")]
|
||||
message = "ℹ️ [b]Character sheet format:[/b]"
|
||||
for column_name in column_names:
|
||||
message += f"{column_name} _\n"
|
||||
return message
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
name, level, strength, dexterity, constitution, intelligence, wisdom, charisma, max_hp, armor_class = \
|
||||
args.match(r"([\w ]+\w)\s*"
|
||||
r"LV\s+(\d+)\s+"
|
||||
r"STR\s+(\d+)\s+"
|
||||
r"DEX\s+(\d+)\s+"
|
||||
r"COS\s+(\d+)\s+"
|
||||
r"INT\s+(\d+)\s+"
|
||||
r"WIS\s+(\d+)\s+"
|
||||
r"CHA\s+(\d+)\s+"
|
||||
r"MAXHP\s+(\d+)\s+"
|
||||
r"AC\s+(\d+)", re.IGNORECASE)
|
||||
character_sheet = args.joined()
|
||||
|
||||
if character_sheet == "":
|
||||
await data.reply(self._syntax())
|
||||
return
|
||||
|
||||
creator = await data.get_author()
|
||||
|
||||
name, rest = character_sheet.split("\n", 1)
|
||||
|
||||
character = self.alchemy.DndCharacter(name=name, creator=creator, **self._parse(rest))
|
||||
data.session.add(character)
|
||||
|
||||
try:
|
||||
int(name)
|
||||
except ValueError:
|
||||
pass
|
||||
else:
|
||||
raise CommandError("Character names cannot be composed of only a number.")
|
||||
author = await data.get_author(error_if_none=True)
|
||||
char = self.alchemy.DndCharacter(name=name,
|
||||
level=level,
|
||||
strength=strength,
|
||||
dexterity=dexterity,
|
||||
constitution=constitution,
|
||||
intelligence=intelligence,
|
||||
wisdom=wisdom,
|
||||
charisma=charisma,
|
||||
max_hp=max_hp,
|
||||
armor_class=armor_class,
|
||||
creator=author)
|
||||
data.session.add(char)
|
||||
await data.session_commit()
|
||||
await data.reply(f"✅ Character [b]{char.name}[/b] ([c]{char.character_id}[/c]) was created!")
|
||||
await data.session_commit()
|
||||
except Exception as err:
|
||||
# THIS IS INTENDED
|
||||
if err.__class__.__name__ == "IntegrityError":
|
||||
param_name = re.search(r'in column "(\S+)"', err.args[0]).group(1)
|
||||
raise CommandError(f"Mandatory parameter '{param_name}' is missing.")
|
||||
raise
|
||||
|
||||
await data.reply(f"✅ Character [b]{character.name}[/b] created!")
|
||||
|
|
|
@ -1,94 +0,0 @@
|
|||
import typing
|
||||
import random
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import plusformat
|
||||
from ..tables import DndCharacter, DndActiveCharacter
|
||||
|
||||
|
||||
class DndrollCommand(Command):
|
||||
name: str = "dndroll"
|
||||
|
||||
description: str = "Roll as the active DnD character."
|
||||
|
||||
aliases = ["dr", "dndr", "droll"]
|
||||
|
||||
syntax = "{stat} [proficiency] [modifier]"
|
||||
|
||||
tables = {DndCharacter, DndActiveCharacter}
|
||||
|
||||
@staticmethod
|
||||
def _roll():
|
||||
return random.randrange(1, 21)
|
||||
|
||||
_roll_string = "1d20"
|
||||
|
||||
async def run(self, args: CommandArgs, data: CommandData) -> None:
|
||||
author = await data.get_author(error_if_none=True)
|
||||
if author.dnd_active_character is None:
|
||||
raise CommandError("You don't have an active character.")
|
||||
char: DndCharacter = author.dnd_active_character.character
|
||||
stat: str = args[0]
|
||||
second: typing.Optional[str] = args.optional(1)
|
||||
third: typing.Optional[str] = args.optional(2)
|
||||
|
||||
if third:
|
||||
extra_mod: int = int(third)
|
||||
else:
|
||||
extra_mod: int = 0
|
||||
|
||||
if second:
|
||||
if second.startswith("e") or second.startswith("x"):
|
||||
proficiency_mul: float = 2.0
|
||||
proficiency_name: str = " with Expertise"
|
||||
elif second.startswith("f") or second.startswith("n") or second.startswith("c"):
|
||||
proficiency_mul: float = 1.0
|
||||
proficiency_name: str = " with Proficiency"
|
||||
elif second.startswith("h") or second == "/" or second.startswith("m"):
|
||||
proficiency_mul: float = 0.5
|
||||
proficiency_name: str = " with Half Proficiency"
|
||||
elif second.startswith("h") or second == "/" or second.startswith("m"):
|
||||
proficiency_mul: float = 0.0
|
||||
proficiency_name: str = " [i]without Proficiency[/i]"
|
||||
else:
|
||||
raise CommandError(f"Unknown proficiency type '{second}'")
|
||||
proficiency_mod: int = int(char.proficiency_bonus * proficiency_mul)
|
||||
else:
|
||||
proficiency_name: str = ""
|
||||
proficiency_mod: int = 0
|
||||
|
||||
if stat.startswith("st") or stat.startswith("fo"):
|
||||
stat_mod: int = char.strength_mod
|
||||
stat_name: str = "[i]STR[/i]"
|
||||
elif stat.startswith("de"):
|
||||
stat_mod: int = char.dexterity_mod
|
||||
stat_name: str = "[i]DEX[/i]"
|
||||
elif stat.startswith("co"):
|
||||
stat_mod: int = char.constitution_mod
|
||||
stat_name: str = "[i]CON[/i]"
|
||||
elif stat.startswith("in"):
|
||||
stat_mod: int = char.intelligence_mod
|
||||
stat_name: str = "[i]INT[/i]"
|
||||
elif stat.startswith("wi") or stat.startswith("sa"):
|
||||
stat_mod: int = char.wisdom_mod
|
||||
stat_name: str = "[i]WIS[/i]"
|
||||
elif stat.startswith("ch") or stat.startswith("ca"):
|
||||
stat_mod: int = char.charisma_mod
|
||||
stat_name: str = "[i]CHA[/i]"
|
||||
else:
|
||||
raise CommandError(f"Unknown stat '{stat}'")
|
||||
|
||||
total_mod = stat_mod + proficiency_mod + extra_mod
|
||||
|
||||
roll = self._roll()
|
||||
|
||||
result = roll + total_mod
|
||||
|
||||
await data.reply(f"🎲 Rolling {stat_name}{proficiency_name}{plusformat(extra_mod, empty_if_zero=True)}:\n"
|
||||
f"{self._roll_string}"
|
||||
f"{plusformat(stat_mod, empty_if_zero=True)}"
|
||||
f"{plusformat(proficiency_mod, empty_if_zero=True)}"
|
||||
f"{plusformat(extra_mod, empty_if_zero=True)}"
|
||||
f" = "
|
||||
f"{roll}{plusformat(total_mod, empty_if_zero=True)}"
|
||||
f" = "
|
||||
f"[b]{result}[/b]")
|
|
@ -1,26 +0,0 @@
|
|||
import typing
|
||||
import random
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import plusformat
|
||||
from .dndroll import DndrollCommand
|
||||
from ..tables import DndCharacter, DndActiveCharacter
|
||||
|
||||
|
||||
class DndrolladvCommand(DndrollCommand):
|
||||
name: str = "dndrolladv"
|
||||
|
||||
description: str = "Roll with advantage as the active DnD character."
|
||||
|
||||
aliases = ["dra", "dndra", "drolladv"]
|
||||
|
||||
syntax = "{stat} [proficiency] [modifier]"
|
||||
|
||||
tables = {DndCharacter, DndActiveCharacter}
|
||||
|
||||
@staticmethod
|
||||
def _roll():
|
||||
first = random.randrange(1, 21)
|
||||
second = random.randrange(1, 21)
|
||||
return max(first, second)
|
||||
|
||||
_roll_string = "2d20h1"
|
|
@ -1,26 +0,0 @@
|
|||
import typing
|
||||
import random
|
||||
from royalnet.commands import *
|
||||
from royalnet.utils import plusformat
|
||||
from .dndroll import DndrollCommand
|
||||
from ..tables import DndCharacter, DndActiveCharacter
|
||||
|
||||
|
||||
class DndrolldisCommand(DndrollCommand):
|
||||
name: str = "dndrolldis"
|
||||
|
||||
description: str = "Roll with disadvantage as the active DnD character."
|
||||
|
||||
aliases = ["drd", "dndrd", "drolldis"]
|
||||
|
||||
syntax = "{stat} [proficiency] [modifier]"
|
||||
|
||||
tables = {DndCharacter, DndActiveCharacter}
|
||||
|
||||
@staticmethod
|
||||
def _roll():
|
||||
first = random.randrange(1, 21)
|
||||
second = random.randrange(1, 21)
|
||||
return min(first, second)
|
||||
|
||||
_roll_string = "2d20l1"
|
|
@ -1,6 +1,7 @@
|
|||
from sqlalchemy import *
|
||||
from sqlalchemy.orm import *
|
||||
from sqlalchemy.ext.declarative import *
|
||||
from ..utils import DndProficiencyType
|
||||
|
||||
|
||||
class DndCharacter:
|
||||
|
@ -20,71 +21,267 @@ class DndCharacter:
|
|||
|
||||
@declared_attr
|
||||
def name(self):
|
||||
return Column(String)
|
||||
return Column(String, nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def strength_score(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@property
|
||||
def strength(self):
|
||||
return Column(Integer)
|
||||
|
||||
@property
|
||||
def strength_mod(self):
|
||||
return (self.strength - 10) // 2
|
||||
return (self.strength_score - 10) // 2
|
||||
|
||||
@declared_attr
|
||||
def dexterity_score(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@property
|
||||
def dexterity(self):
|
||||
return Column(Integer)
|
||||
|
||||
@property
|
||||
def dexterity_mod(self):
|
||||
return (self.dexterity - 10) // 2
|
||||
return (self.dexterity_score - 10) // 2
|
||||
|
||||
@declared_attr
|
||||
def constitution_score(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@property
|
||||
def constitution(self):
|
||||
return Column(Integer)
|
||||
|
||||
@property
|
||||
def constitution_mod(self):
|
||||
return (self.constitution - 10) // 2
|
||||
return (self.constitution_score - 10) // 2
|
||||
|
||||
@declared_attr
|
||||
def intelligence_score(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@property
|
||||
def intelligence(self):
|
||||
return Column(Integer)
|
||||
|
||||
@property
|
||||
def intelligence_mod(self):
|
||||
return (self.intelligence - 10) // 2
|
||||
return (self.intelligence_score - 10) // 2
|
||||
|
||||
@declared_attr
|
||||
def wisdom_score(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@property
|
||||
def wisdom(self):
|
||||
return Column(Integer)
|
||||
|
||||
@property
|
||||
def wisdom_mod(self):
|
||||
return (self.wisdom - 10) // 2
|
||||
return (self.wisdom_score - 10) // 2
|
||||
|
||||
@declared_attr
|
||||
def charisma(self):
|
||||
return Column(Integer)
|
||||
def charisma_score(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@property
|
||||
def charisma_mod(self):
|
||||
return (self.charisma - 10) // 2
|
||||
def charisma(self):
|
||||
return (self.charisma_score - 10) // 2
|
||||
|
||||
@declared_attr
|
||||
def level(self):
|
||||
return Column(Integer)
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@property
|
||||
def proficiency_bonus(self):
|
||||
return ((self.level - 1) // 4) + 2
|
||||
|
||||
@declared_attr
|
||||
def current_hp(self):
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def max_hp(self):
|
||||
return Column(Integer)
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def armor_class(self):
|
||||
return Column(Integer)
|
||||
return Column(Integer, nullable=False)
|
||||
|
||||
@declared_attr
|
||||
def strength_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def dexterity_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def constitution_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def intelligence_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def wisdom_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def charisma_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def acrobatics_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def animal_handling_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def arcana_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def athletics_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def deception_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def history_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def insight_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def intimidation_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def investigation_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def medicine_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def nature_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def perception_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def performance_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def persuasion_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def religion_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def sleight_of_hand_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def stealth_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@declared_attr
|
||||
def survival_proficiency(self):
|
||||
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
||||
|
||||
@property
|
||||
def strength_save(self):
|
||||
return self.strength + self.proficiency_bonus * self.strength_proficiency.value
|
||||
|
||||
@property
|
||||
def dexterity_save(self):
|
||||
return self.dexterity + self.proficiency_bonus * self.dexterity_proficiency.value
|
||||
|
||||
@property
|
||||
def constitution_save(self):
|
||||
return self.constitution + self.proficiency_bonus * self.constitution_proficiency.value
|
||||
|
||||
@property
|
||||
def intelligence_save(self):
|
||||
return self.intelligence + self.proficiency_bonus * self.intelligence_proficiency.value
|
||||
|
||||
@property
|
||||
def wisdom_save(self):
|
||||
return self.wisdom + self.proficiency_bonus * self.wisdom_proficiency.value
|
||||
|
||||
@property
|
||||
def charisma_save(self):
|
||||
return self.charisma + self.proficiency_bonus * self.charisma_proficiency.value
|
||||
|
||||
@property
|
||||
def acrobatics(self):
|
||||
return self.dexterity + self.proficiency_bonus * self.acrobatics_proficiency.value
|
||||
|
||||
@property
|
||||
def animal_handling(self):
|
||||
return self.wisdom + self.proficiency_bonus * self.animal_handling_proficiency.value
|
||||
|
||||
@property
|
||||
def arcana(self):
|
||||
return self.intelligence + self.proficiency_bonus * self.arcana_proficiency.value
|
||||
|
||||
@property
|
||||
def athletics(self):
|
||||
return self.strength + self.proficiency_bonus * self.athletics_proficiency.value
|
||||
|
||||
@property
|
||||
def deception(self):
|
||||
return self.charisma + self.proficiency_bonus * self.deception_proficiency.value
|
||||
|
||||
@property
|
||||
def history(self):
|
||||
return self.intelligence + self.proficiency_bonus * self.history_proficiency.value
|
||||
|
||||
@property
|
||||
def insight(self):
|
||||
return self.wisdom + self.proficiency_bonus * self.insight_proficiency.value
|
||||
|
||||
@property
|
||||
def intimidation(self):
|
||||
return self.charisma + self.proficiency_bonus * self.intimidation_proficiency.value
|
||||
|
||||
@property
|
||||
def investigation(self):
|
||||
return self.intelligence + self.proficiency_bonus * self.investigation_proficiency.value
|
||||
|
||||
@property
|
||||
def medicine(self):
|
||||
return self.wisdom + self.proficiency_bonus * self.medicine_proficiency.value
|
||||
|
||||
@property
|
||||
def nature(self):
|
||||
return self.intelligence + self.proficiency_bonus * self.nature_proficiency.value
|
||||
|
||||
@property
|
||||
def perception(self):
|
||||
return self.wisdom + self.proficiency_bonus * self.perception_proficiency.value
|
||||
|
||||
@property
|
||||
def performance(self):
|
||||
return self.charisma + self.proficiency_bonus * self.performance_proficiency.value
|
||||
|
||||
@property
|
||||
def persuasion(self):
|
||||
return self.charisma + self.proficiency_bonus * self.persuasion_proficiency.value
|
||||
|
||||
@property
|
||||
def religion(self):
|
||||
return self.intelligence + self.proficiency_bonus * self.religion_proficiency.value
|
||||
|
||||
@property
|
||||
def sleight_of_hand(self):
|
||||
return self.dexterity + self.proficiency_bonus * self.sleight_of_hand_proficiency.value
|
||||
|
||||
@property
|
||||
def stealth(self):
|
||||
return self.dexterity + self.proficiency_bonus * self.stealth_proficiency.value
|
||||
|
||||
@property
|
||||
def survival(self):
|
||||
return self.wisdom + self.proficiency_bonus * self.survival_proficiency.value
|
||||
|
||||
def __repr__(self):
|
||||
return f"<{self.__class__.__qualname__} {self.name}>"
|
||||
|
@ -92,14 +289,13 @@ class DndCharacter:
|
|||
def __str__(self):
|
||||
return f"{self.name}"
|
||||
|
||||
def character_sheet(self):
|
||||
return f"{self.name}\n" \
|
||||
f"LV {self.level}\n\n" \
|
||||
f"STR {self.strength}\n" \
|
||||
f"DEX {self.dexterity}\n" \
|
||||
f"CON {self.constitution}\n" \
|
||||
f"INT {self.intelligence}\n" \
|
||||
f"WIS {self.wisdom}\n" \
|
||||
f"CHA {self.charisma}\n\n" \
|
||||
f"MAXHP {self.max_hp}\n" \
|
||||
f"AC {self.armor_class}\n" \
|
||||
def character_sheet(self) -> str:
|
||||
columns = list(self.__class__.__table__.columns)
|
||||
column_names = [column.name for column in columns if (not column.primary_key and
|
||||
not column.foreign_keys and
|
||||
column.name != "name")]
|
||||
message = f"[b]{self.name}[/b]\n"
|
||||
for column_name in column_names:
|
||||
value = self.__getattribute__(column_name)
|
||||
message += f"{column_name} {value}\n"
|
||||
return message
|
||||
|
|
3
royalnet/packs/rpg/utils/__init__.py
Normal file
3
royalnet/packs/rpg/utils/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
|||
from .dndproficiencytype import DndProficiencyType
|
||||
|
||||
__all__ = ["DndProficiencyType"]
|
11
royalnet/packs/rpg/utils/dndproficiencytype.py
Normal file
11
royalnet/packs/rpg/utils/dndproficiencytype.py
Normal file
|
@ -0,0 +1,11 @@
|
|||
import enum
|
||||
|
||||
|
||||
class DndProficiencyType(enum.Enum):
|
||||
NONE = 0
|
||||
HALF_PROFICIENCY = 0.5
|
||||
FULL_PROFICIENCY = 1
|
||||
EXPERTISE = 2
|
||||
|
||||
def __str__(self):
|
||||
return str(self.value)
|
Loading…
Reference in a new issue