2019-12-04 00:47:00 +00:00
|
|
|
import math
|
2019-11-11 09:34:05 +00:00
|
|
|
from sqlalchemy import *
|
|
|
|
from sqlalchemy.orm import *
|
|
|
|
from sqlalchemy.ext.declarative import *
|
2020-02-22 01:16:54 +00:00
|
|
|
from ..types import DndProficiencyType
|
2020-03-14 00:57:29 +00:00
|
|
|
from royalnet.utils import JSON
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
|
|
|
|
class DndCharacter:
|
|
|
|
__tablename__ = "dndcharacters"
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def character_id(self):
|
|
|
|
return Column(Integer, primary_key=True)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def creator_id(self):
|
|
|
|
return Column(Integer, ForeignKey("users.uid"))
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def creator(self):
|
|
|
|
return relationship("User", foreign_keys=self.creator_id, backref="dndcharacters_created")
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def name(self):
|
2020-03-16 19:03:49 +00:00
|
|
|
return Column(String, nullable=False, unique=True)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def strength_score(self):
|
|
|
|
return Column(Integer, nullable=False)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def strength(self):
|
|
|
|
return (self.strength_score - 10) // 2
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def dexterity_score(self):
|
|
|
|
return Column(Integer, nullable=False)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def dexterity(self):
|
|
|
|
return (self.dexterity_score - 10) // 2
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def constitution_score(self):
|
|
|
|
return Column(Integer, nullable=False)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def constitution(self):
|
|
|
|
return (self.constitution_score - 10) // 2
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def intelligence_score(self):
|
|
|
|
return Column(Integer, nullable=False)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def intelligence(self):
|
|
|
|
return (self.intelligence_score - 10) // 2
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def wisdom_score(self):
|
|
|
|
return Column(Integer, nullable=False)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def wisdom(self):
|
|
|
|
return (self.wisdom_score - 10) // 2
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def charisma_score(self):
|
|
|
|
return Column(Integer, nullable=False)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def charisma(self):
|
|
|
|
return (self.charisma_score - 10) // 2
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def level(self):
|
|
|
|
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, nullable=False)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def armor_class(self):
|
|
|
|
return Column(Integer, nullable=False)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def strength_save_proficiency(self):
|
|
|
|
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def dexterity_save_proficiency(self):
|
|
|
|
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def constitution_save_proficiency(self):
|
|
|
|
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def intelligence_save_proficiency(self):
|
|
|
|
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def wisdom_save_proficiency(self):
|
|
|
|
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
|
|
|
|
|
|
|
@declared_attr
|
|
|
|
def charisma_save_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)
|
|
|
|
|
2020-03-04 18:29:33 +00:00
|
|
|
@declared_attr
|
|
|
|
def initiative_proficiency(self):
|
|
|
|
return Column(Enum(DndProficiencyType), nullable=False, default=DndProficiencyType.NONE)
|
|
|
|
|
2019-11-11 09:34:05 +00:00
|
|
|
@property
|
|
|
|
def strength_save(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.strength + math.floor(self.proficiency_bonus * self.strength_save_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def dexterity_save(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.dexterity + math.floor(self.proficiency_bonus * self.dexterity_save_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def constitution_save(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.constitution + math.floor(self.proficiency_bonus * self.constitution_save_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def intelligence_save(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.intelligence + math.floor(self.proficiency_bonus * self.intelligence_save_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def wisdom_save(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.wisdom + math.floor(self.proficiency_bonus * self.wisdom_save_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def charisma_save(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.charisma + math.floor(self.proficiency_bonus * self.charisma_save_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def acrobatics(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.dexterity + math.floor(self.proficiency_bonus * self.acrobatics_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def animal_handling(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.wisdom + math.floor(self.proficiency_bonus * self.animal_handling_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def arcana(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.intelligence + math.floor(self.proficiency_bonus * self.arcana_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def athletics(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.strength + math.floor(self.proficiency_bonus * self.athletics_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def deception(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.charisma + math.floor(self.proficiency_bonus * self.deception_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def history(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.intelligence + math.floor(self.proficiency_bonus * self.history_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def insight(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.wisdom + math.floor(self.proficiency_bonus * self.insight_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def intimidation(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.charisma + math.floor(self.proficiency_bonus * self.intimidation_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def investigation(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.intelligence + math.floor(self.proficiency_bonus * self.investigation_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def medicine(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.wisdom + math.floor(self.proficiency_bonus * self.medicine_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def nature(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.intelligence + math.floor(self.proficiency_bonus * self.nature_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def perception(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.wisdom + math.floor(self.proficiency_bonus * self.perception_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def performance(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.charisma + math.floor(self.proficiency_bonus * self.performance_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def persuasion(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.charisma + math.floor(self.proficiency_bonus * self.persuasion_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def religion(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.intelligence + math.floor(self.proficiency_bonus * self.religion_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def sleight_of_hand(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.dexterity + math.floor(self.proficiency_bonus * self.sleight_of_hand_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def stealth(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.dexterity + math.floor(self.proficiency_bonus * self.stealth_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
|
|
|
@property
|
|
|
|
def survival(self):
|
2019-12-04 00:47:00 +00:00
|
|
|
return self.wisdom + math.floor(self.proficiency_bonus * self.survival_proficiency.value)
|
2019-11-11 09:34:05 +00:00
|
|
|
|
2020-03-04 18:29:33 +00:00
|
|
|
@property
|
|
|
|
def initiative(self):
|
|
|
|
return self.dexterity + math.floor(self.proficiency_bonus * self.initiative_proficiency.value)
|
|
|
|
|
2019-11-11 09:34:05 +00:00
|
|
|
def __repr__(self):
|
|
|
|
return f"<{self.__class__.__qualname__} {self.name}>"
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return f"{self.name}"
|
|
|
|
|
2020-03-16 19:03:49 +00:00
|
|
|
def to_edit_string(self) -> str:
|
2019-11-11 09:34:05 +00:00
|
|
|
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
|
2020-03-14 00:57:29 +00:00
|
|
|
|
|
|
|
def json(self) -> JSON:
|
|
|
|
return {
|
|
|
|
"creator": self.creator.json() if self.creator else None,
|
|
|
|
"name": self.name,
|
|
|
|
"level": self.level,
|
|
|
|
"hp": {
|
|
|
|
"current": self.current_hp,
|
|
|
|
"max": self.max_hp
|
|
|
|
},
|
|
|
|
"armor_class": self.armor_class,
|
|
|
|
"strength": {
|
|
|
|
"score": self.strength_score,
|
|
|
|
"modifier": self.strength,
|
|
|
|
"save": self.strength_save,
|
|
|
|
"save_proficiency": self.strength_save_proficiency.value
|
|
|
|
},
|
|
|
|
"dexterity": {
|
|
|
|
"score": self.dexterity_score,
|
|
|
|
"modifier": self.dexterity,
|
|
|
|
"save": self.dexterity_save,
|
|
|
|
"save_proficiency": self.dexterity_save_proficiency.value
|
|
|
|
},
|
|
|
|
"constitution": {
|
|
|
|
"score": self.constitution_score,
|
|
|
|
"modifier": self.constitution,
|
|
|
|
"save": self.constitution_save,
|
|
|
|
"save_proficiency": self.constitution_save_proficiency.value
|
|
|
|
},
|
|
|
|
"intelligence": {
|
|
|
|
"score": self.intelligence_score,
|
|
|
|
"modifier": self.intelligence,
|
|
|
|
"save": self.intelligence_save,
|
|
|
|
"save_proficiency": self.intelligence_save_proficiency.value
|
|
|
|
},
|
|
|
|
"wisdom": {
|
|
|
|
"score": self.wisdom_score,
|
|
|
|
"modifier": self.wisdom,
|
|
|
|
"save": self.wisdom_save,
|
|
|
|
"save_proficiency": self.wisdom_save_proficiency.value
|
|
|
|
},
|
|
|
|
"charisma": {
|
|
|
|
"score": self.charisma_score,
|
|
|
|
"modifier": self.charisma,
|
|
|
|
"save": self.charisma_save,
|
|
|
|
"save_proficiency": self.charisma_save_proficiency.value
|
|
|
|
},
|
|
|
|
"acrobatics": {
|
|
|
|
"modifier": self.acrobatics,
|
|
|
|
"proficiency": self.acrobatics_proficiency.value
|
|
|
|
},
|
|
|
|
"animal_handling": {
|
|
|
|
"modifier": self.animal_handling,
|
|
|
|
"proficiency": self.animal_handling_proficiency.value
|
|
|
|
},
|
|
|
|
"arcana": {
|
|
|
|
"modifier": self.arcana,
|
|
|
|
"proficiency": self.arcana_proficiency.value
|
|
|
|
},
|
|
|
|
"athletics": {
|
|
|
|
"modifier": self.athletics,
|
|
|
|
"proficiency": self.athletics_proficiency.value
|
|
|
|
},
|
|
|
|
"deception": {
|
|
|
|
"modifier": self.deception,
|
|
|
|
"proficiency": self.deception_proficiency.value
|
|
|
|
},
|
|
|
|
"history": {
|
|
|
|
"modifier": self.history,
|
|
|
|
"proficiency": self.history_proficiency.value
|
|
|
|
},
|
|
|
|
"insight": {
|
|
|
|
"modifier": self.insight,
|
|
|
|
"proficiency": self.insight_proficiency.value
|
|
|
|
},
|
|
|
|
"intimidation": {
|
|
|
|
"modifier": self.intimidation,
|
|
|
|
"proficiency": self.intimidation_proficiency.value
|
|
|
|
},
|
|
|
|
"investigation": {
|
|
|
|
"modifier": self.investigation,
|
|
|
|
"proficiency": self.investigation_proficiency.value
|
|
|
|
},
|
|
|
|
"medicine": {
|
|
|
|
"modifier": self.medicine,
|
|
|
|
"proficiency": self.medicine_proficiency.value
|
|
|
|
},
|
|
|
|
"nature": {
|
|
|
|
"modifier": self.nature,
|
|
|
|
"proficiency": self.nature_proficiency.value
|
|
|
|
},
|
|
|
|
"perception": {
|
|
|
|
"modifier": self.perception,
|
|
|
|
"proficiency": self.perception_proficiency.value
|
|
|
|
},
|
|
|
|
"performance": {
|
|
|
|
"modifier": self.performance,
|
|
|
|
"proficiency": self.performance_proficiency.value
|
|
|
|
},
|
|
|
|
"persuasion": {
|
|
|
|
"modifier": self.persuasion,
|
|
|
|
"proficiency": self.persuasion_proficiency.value
|
|
|
|
},
|
|
|
|
"religion": {
|
|
|
|
"modifier": self.religion,
|
|
|
|
"proficiency": self.religion_proficiency.value
|
|
|
|
},
|
|
|
|
"sleight_of_hand": {
|
|
|
|
"modifier": self.sleight_of_hand,
|
|
|
|
"proficiency": self.sleight_of_hand_proficiency.value
|
|
|
|
},
|
|
|
|
"stealth": {
|
|
|
|
"modifier": self.stealth,
|
|
|
|
"proficiency": self.stealth_proficiency.value
|
|
|
|
},
|
|
|
|
"survival": {
|
|
|
|
"modifier": self.survival,
|
|
|
|
"proficiency": self.survival_proficiency.value
|
|
|
|
},
|
|
|
|
"initiative": {
|
|
|
|
"modifier": self.initiative,
|
|
|
|
"proficiency": self.initiative_proficiency.value
|
|
|
|
}
|
|
|
|
}
|