2024-04-14 11:37:34 -07:00
|
|
|
from collections import defaultdict
|
|
|
|
|
2024-04-28 14:30:47 -07:00
|
|
|
from sqlalchemy import ForeignKey
|
|
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
2024-02-18 19:30:41 -08:00
|
|
|
|
2024-04-28 14:30:47 -07:00
|
|
|
from ttfrog.db.base import BaseObject, SavingThrowsMixin, SkillsMixin
|
2024-02-18 19:30:41 -08:00
|
|
|
|
|
|
|
__all__ = [
|
2024-03-26 00:53:21 -07:00
|
|
|
"ClassAttributeMap",
|
|
|
|
"ClassAttribute",
|
|
|
|
"ClassAttributeOption",
|
|
|
|
"CharacterClass",
|
2024-02-18 19:30:41 -08:00
|
|
|
]
|
|
|
|
|
|
|
|
|
2024-04-20 20:35:07 -07:00
|
|
|
class ClassAttributeMap(BaseObject):
|
2024-02-18 19:30:41 -08:00
|
|
|
__tablename__ = "class_attribute_map"
|
2024-04-28 14:30:47 -07:00
|
|
|
class_attribute_id: Mapped[int] = mapped_column(ForeignKey("class_attribute.id"), primary_key=True)
|
|
|
|
character_class_id: Mapped[int] = mapped_column(ForeignKey("character_class.id"), primary_key=True)
|
|
|
|
level: Mapped[int] = mapped_column(nullable=False, info={"min": 1, "max": 20}, default=1)
|
2024-03-26 21:58:04 -07:00
|
|
|
attribute = relationship("ClassAttribute", uselist=False, viewonly=True, lazy="immediate")
|
2024-02-18 19:30:41 -08:00
|
|
|
|
|
|
|
|
2024-04-20 20:35:07 -07:00
|
|
|
class ClassAttribute(BaseObject):
|
2024-02-18 19:30:41 -08:00
|
|
|
__tablename__ = "class_attribute"
|
2024-04-28 14:30:47 -07:00
|
|
|
id: Mapped[int] = mapped_column(init=False, primary_key=True, autoincrement=True)
|
|
|
|
name: Mapped[str] = mapped_column(nullable=False)
|
2024-03-26 21:58:04 -07:00
|
|
|
options = relationship("ClassAttributeOption", cascade="all,delete,delete-orphan", lazy="immediate")
|
2024-02-26 01:12:45 -08:00
|
|
|
|
|
|
|
def __repr__(self):
|
|
|
|
return f"{self.id}: {self.name}"
|
|
|
|
|
|
|
|
|
2024-04-20 20:35:07 -07:00
|
|
|
class ClassAttributeOption(BaseObject):
|
2024-02-26 01:12:45 -08:00
|
|
|
__tablename__ = "class_attribute_option"
|
2024-04-28 14:30:47 -07:00
|
|
|
id: Mapped[int] = mapped_column(init=False, primary_key=True, autoincrement=True)
|
|
|
|
name: Mapped[str] = mapped_column(nullable=False)
|
|
|
|
attribute_id: Mapped[int] = mapped_column(ForeignKey("class_attribute.id"), nullable=False)
|
2024-02-18 19:30:41 -08:00
|
|
|
|
|
|
|
|
2024-04-20 20:35:07 -07:00
|
|
|
class CharacterClass(BaseObject, SavingThrowsMixin, SkillsMixin):
|
2024-02-18 19:30:41 -08:00
|
|
|
__tablename__ = "character_class"
|
2024-04-28 14:30:47 -07:00
|
|
|
id: Mapped[int] = mapped_column(init=False, primary_key=True, autoincrement=True)
|
|
|
|
name: Mapped[str] = mapped_column(index=True, unique=True)
|
|
|
|
hit_dice: Mapped[str] = mapped_column(default="1d6")
|
|
|
|
hit_dice_stat: Mapped[str] = mapped_column(default="")
|
|
|
|
proficiencies: Mapped[str] = mapped_column(default="")
|
2024-03-26 21:58:04 -07:00
|
|
|
attributes = relationship("ClassAttributeMap", cascade="all,delete,delete-orphan", lazy="immediate")
|
|
|
|
|
|
|
|
@property
|
|
|
|
def attributes_by_level(self):
|
2024-04-14 11:37:34 -07:00
|
|
|
by_level = defaultdict(list)
|
2024-03-26 21:58:04 -07:00
|
|
|
for mapping in self.attributes:
|
|
|
|
by_level[mapping.level] = {mapping.attribute.name: mapping.attribute}
|
|
|
|
return by_level
|