from flask_sqlalchemy import SQLAlchemy from ..models import db, BaseModel class CharacterClass(BaseModel): __tablename__ = 'character_class' name = db.Column(db.String(50), unique=True, nullable=False) bucket = db.Column(db.String(50)) frequency_modifier = db.Column(db.Integer, default=1) prime_requisite = db.Column(db.String(3)) hit_die_size = db.Column(db.Integer) maximum_level = db.Column(db.Integer) armour_modifier = db.Column(db.Integer) melee_light = db.Column(db.Integer) melee_medium = db.Column(db.Integer) melee_heavy = db.Column(db.Integer) ranged_light = db.Column(db.Integer) ranged_heavy = db.Column(db.Integer) def __repr__(self): return ''.format(self.name) class ClassLevelProgression(BaseModel): __tablename__ = 'class_progression' level = db.Column(db.Integer) attack_throw = db.Column(db.Integer) save_petrification_paralysis = db.Column(db.Integer) save_poison_death = db.Column(db.Integer) save_blast_breath = db.Column(db.Integer) save_staffs_wands = db.Column(db.Integer) save_spells = db.Column(db.Integer) guild_id = db.Column(db.Integer, db.ForeignKey('character_class.id'), nullable=False) guild = db.relationship('CharacterClass', backref=db.backref('progressions', lazy=True)) def __repr__(self): return ''.format(self.level, self.guild.name) class EquipmentArmour(BaseModel): __tablename__ = 'eq_armour' name = db.Column(db.String(50), unique=True, nullable=False) gp_value = db.Column(db.Integer, nullable=False) ac_mod = db.Column(db.Integer, nullable=False) def __repr__(self): return ''.format(self.name) class EquipmentRangedWeapon(BaseModel): __tablename__ = 'eq_ranged_wep' name = db.Column(db.String(50), unique=True, nullable=False) bucket = db.Column(db.String(20), nullable=False) gp_value = db.Column(db.Integer, nullable=False) damage_die = db.Column(db.String(10), nullable=False) def __repr__(self): return ''.format(self.name) class EquipmentMeleeWeapon(BaseModel): __tablename__ = 'eq_melee_wep' name = db.Column(db.String(50), unique=False, nullable=False) bucket = db.Column(db.String(20), nullable=False) gp_value = db.Column(db.Integer, nullable=False) damage_die = db.Column(db.String(10), nullable=False) two_handed = db.Column(db.Boolean, nullable=False) def __repr__(self): return ''.format(self.name) class CharacterNPC(BaseModel): __tablename__ = 'npcs' name = db.Column(db.String(50), unique=False, nullable=True) level = db.Column(db.Integer, nullable=False) alignment = db.Column(db.String(20), unique=False, nullable=False) hit_points = db.Column(db.Integer, nullable=False) strength = db.Column(db.Integer, nullable=False) intelligence = db.Column(db.Integer, nullable=False) wisdom = db.Column(db.Integer, nullable=False) dexterity = db.Column(db.Integer, nullable=False) constitution = db.Column(db.Integer, nullable=False) charisma = db.Column(db.Integer, nullable=False) guild_id = db.Column(db.Integer, db.ForeignKey('character_class.id'), nullable=False) guild = db.relationship('CharacterClass', backref=db.backref('npcs', lazy=True)) melee_id = db.Column(db.Integer, db.ForeignKey('eq_melee_wep.id'), nullable=False) melee = db.relationship('EquipmentMeleeWeapon') ranged_id = db.Column(db.Integer, db.ForeignKey('eq_ranged_wep.id'), nullable=True) ranged = db.relationship('EquipmentRangedWeapon') armour_id = db.Column(db.Integer, db.ForeignKey('eq_armour.id'), nullable=False) armour = db.relationship('EquipmentArmour') def __repr__(self): return ''.format(self.name) @staticmethod def calculate_attr_mod(attr): mod = 0 if attr <= 3: mod = -3 elif attr >= 4 and attr <= 5: mod = -2 elif attr >= 6 and attr <= 8: mod = -1 elif attr >= 9 and attr <= 12: mod = 0 elif attr >= 13 and attr <= 15: mod = 1 elif attr >= 16 and attr <= 16: mod = 2 elif attr >= 18: mod = 3 return mod @property def roll20_format(self): npc_dict = { 'name': self.name, 'level': self.level, 'hp': self.hit_points, 'guild': self.guild.name, 'alignment': self.alignment, "attack_throw": self.attack_throw, 'attributes': { 'str': self.strength, 'int': self.intelligence, 'wis': self.wisdom, 'dex': self.dexterity, 'con': self.constitution, 'chr': self.charisma }, 'attribute_mods': { 'str': self.str_mod, 'int': self.int_mod, 'wis': self.wis_mod, 'dex': self.dex_mod, 'con': self.con_mod, 'chr': self.chr_mod }, "saves": { "pp": self.save_pp, "pd": self.save_pd, "bb": self.save_bb, "sw": self.save_sw, "sp": self.save_sp }, 'armour': { 'name': self.armour.name, 'value': self.armour.gp_value, 'ac_mod': self.armour.ac_mod }, 'melee': { 'name': self.melee.name, 'value': self.melee.gp_value, 'damage': self.melee.damage_die, 'throw_mod': 0, 'two_handed': self.melee.two_handed } } if self.ranged: npc_dict['ranged'] = { 'name': self.ranged.name, 'value': self.ranged.gp_value, 'damage': self.ranged.damage_die, 'throw_mod': 0 } return npc_dict @property def str(self): return self.strength @property def int(self): return self.intelligence @property def wis(self): return self.wisdom @property def dex(self): return self.dexterity @property def con(self): return self.constitution @property def chr(self): return self.charisma @property def str_mod(self): return self.calculate_attr_mod(self.strength) @property def int_mod(self): return self.calculate_attr_mod(self.intelligence) @property def wis_mod(self): return self.calculate_attr_mod(self.wisdom) @property def dex_mod(self): return self.calculate_attr_mod(self.dexterity) @property def con_mod(self): return self.calculate_attr_mod(self.constitution) @property def chr_mod(self): return self.calculate_attr_mod(self.charisma) @property def current_progression(self): return ClassLevelProgression.query.filter_by(guild_id=self.guild.id, level=self.level).first() @property def attack_throw(self): return self.current_progression.attack_throw @property def save_pp(self): return self.current_progression.save_petrification_paralysis @property def save_pd(self): return self.current_progression.save_petrification_paralysis @property def save_bb(self): return self.current_progression.save_blast_breath @property def save_sw(self): return self.current_progression.save_staffs_wands @property def save_sp(self): return self.current_progression.save_spells @property def hp(self): return self.hit_points def update(self, kwargs): # Allows us to update like a dict, used for inserting attributes zip self.__dict__.update(kwargs) admin_models = [CharacterClass, ClassLevelProgression, EquipmentArmour, EquipmentRangedWeapon, EquipmentMeleeWeapon, CharacterNPC]