95 lines
3.7 KiB
Python
95 lines
3.7 KiB
Python
from sqlalchemy import ForeignKey, String
|
|
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
|
|
|
from ttfrog.db.base import BaseObject, EnumField
|
|
from ttfrog.db.schema.constants import DamageType
|
|
from ttfrog.db.schema.modifiers import ModifierMixin
|
|
from ttfrog.db.schema.classes import CharacterClass
|
|
|
|
__all__ = [
|
|
"Item",
|
|
"Spell",
|
|
]
|
|
|
|
|
|
ITEM_TYPES = [
|
|
"ITEM",
|
|
"SPELL",
|
|
"SCROLL",
|
|
"WEAPON",
|
|
"ARMOR",
|
|
"SHIELD",
|
|
]
|
|
|
|
RARITY = [
|
|
"Common",
|
|
"Uncommon",
|
|
"Rare",
|
|
"Very Rare",
|
|
"Legendary",
|
|
"Artifact"
|
|
]
|
|
|
|
|
|
ItemType = EnumField("ItemType", ((k, k) for k in ITEM_TYPES))
|
|
Rarity = EnumField("Rarity", ((k, k) for k in RARITY))
|
|
|
|
|
|
class Item(BaseObject, ModifierMixin):
|
|
__tablename__ = "item"
|
|
__mapper_args__ = {"polymorphic_identity": ItemType.ITEM, "polymorphic_on": "item_type"}
|
|
id: Mapped[int] = mapped_column(init=False, primary_key=True, autoincrement=True)
|
|
name: Mapped[str] = mapped_column(String(collation="NOCASE"), nullable=False, unique=True)
|
|
description: Mapped[str] = mapped_column(String, nullable=True, default=None)
|
|
|
|
item_type: Mapped[ItemType] = mapped_column(default=ItemType.ITEM, nullable=False)
|
|
rarity: Mapped[Rarity] = mapped_column(default=Rarity.Common, nullable=False)
|
|
requires_attunement: Mapped[bool] = mapped_column(nullable=False, default=False)
|
|
|
|
consumable: Mapped[bool] = mapped_column(default=False)
|
|
count: Mapped[int] = mapped_column(nullable=False, default=1)
|
|
|
|
_class_restrictions: Mapped[int] = mapped_column(ForeignKey("character_class.id"), nullable=True, default=None)
|
|
class_restrictions: Mapped["CharacterClass"] = relationship(init=False)
|
|
|
|
# _spells: Mapped[int] = mapped_column(ForeignKey("spell.id"), nullable=True, default=None)
|
|
# spells: Mapped["Spell"] = relationship(init=False)
|
|
|
|
|
|
class Spell(Item):
|
|
__tablename__ = "spell"
|
|
__mapper_args__ = {"polymorphic_identity": ItemType.SPELL}
|
|
id: Mapped[int] = mapped_column(ForeignKey("item.id"), primary_key=True, init=False)
|
|
level: Mapped[int] = mapped_column(nullable=False, info={"min": 0, "max": 9}, default=0)
|
|
concentration: Mapped[bool] = mapped_column(default=False)
|
|
item_type: Mapped[ItemType] = mapped_column(default=ItemType.SPELL, init=False)
|
|
|
|
|
|
class Weapon(Item):
|
|
__tablename__ = "weapon"
|
|
__mapper_args__ = {"polymorphic_identity": ItemType.WEAPON}
|
|
id: Mapped[int] = mapped_column(ForeignKey("item.id"), primary_key=True, init=False)
|
|
damage_die: Mapped[str] = mapped_column(nullable=False, default="1d6")
|
|
damage_type: Mapped[DamageType] = mapped_column(nullable=False, default=DamageType.slashing)
|
|
item_type: Mapped[ItemType] = mapped_column(default=ItemType.WEAPON)
|
|
attack_range: Mapped[int] = mapped_column(nullable=False, info={"min": 0}, default=0)
|
|
attack_range_long: Mapped[int] = mapped_column(nullable=True, info={"min": 0}, default=None)
|
|
targets: Mapped[int] = mapped_column(nullable=False, info={"min": 1}, default=1)
|
|
martial: Mapped[bool] = mapped_column(default=False)
|
|
melee: Mapped[bool] = mapped_column(default=False)
|
|
ammunition: Mapped[bool] = mapped_column(default=False)
|
|
finesse: Mapped[bool] = mapped_column(default=False)
|
|
heavy: Mapped[bool] = mapped_column(default=False)
|
|
light: Mapped[bool] = mapped_column(default=False)
|
|
loading: Mapped[bool] = mapped_column(default=False)
|
|
reach: Mapped[bool] = mapped_column(default=False)
|
|
thrown: Mapped[bool] = mapped_column(default=False)
|
|
two_handed: Mapped[bool] = mapped_column(default=False)
|
|
versatile: Mapped[bool] = mapped_column(default=False)
|
|
silvered: Mapped[bool] = mapped_column(default=False)
|
|
adamantine: Mapped[bool] = mapped_column(default=False)
|
|
|
|
@property
|
|
def ranged(self):
|
|
return self.attack_range > 0
|