You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
8.0 KiB

  1. from flask_sqlalchemy import SQLAlchemy
  2. from ..models import db, BaseModel
  3. class CharacterClass(BaseModel):
  4. __tablename__ = 'character_class'
  5. name = db.Column(db.String(50), unique=True, nullable=False)
  6. bucket = db.Column(db.String(50))
  7. frequency_modifier = db.Column(db.Integer, default=1)
  8. prime_requisite = db.Column(db.String(3))
  9. hit_die_size = db.Column(db.Integer)
  10. maximum_level = db.Column(db.Integer)
  11. armour_modifier = db.Column(db.Integer)
  12. melee_light = db.Column(db.Integer)
  13. melee_medium = db.Column(db.Integer)
  14. melee_heavy = db.Column(db.Integer)
  15. ranged_light = db.Column(db.Integer)
  16. ranged_heavy = db.Column(db.Integer)
  17. def __repr__(self):
  18. return '<CharacterClass {0}>'.format(self.name)
  19. class ClassLevelProgression(BaseModel):
  20. __tablename__ = 'class_progression'
  21. level = db.Column(db.Integer)
  22. attack_throw = db.Column(db.Integer)
  23. save_petrification_paralysis = db.Column(db.Integer)
  24. save_poison_death = db.Column(db.Integer)
  25. save_blast_breath = db.Column(db.Integer)
  26. save_staffs_wands = db.Column(db.Integer)
  27. save_spells = db.Column(db.Integer)
  28. guild_id = db.Column(db.Integer, db.ForeignKey('character_class.id'), nullable=False)
  29. guild = db.relationship('CharacterClass', backref=db.backref('progressions', lazy=True))
  30. def __repr__(self):
  31. return '<LevelProgression {0} {1}>'.format(self.level, self.guild.name)
  32. class EquipmentArmour(BaseModel):
  33. __tablename__ = 'eq_armour'
  34. name = db.Column(db.String(50), unique=True, nullable=False)
  35. gp_value = db.Column(db.Integer, nullable=False)
  36. ac_mod = db.Column(db.Integer, nullable=False)
  37. def __repr__(self):
  38. return '<EquipmentArmour {0}>'.format(self.name)
  39. class EquipmentRangedWeapon(BaseModel):
  40. __tablename__ = 'eq_ranged_wep'
  41. name = db.Column(db.String(50), unique=True, nullable=False)
  42. bucket = db.Column(db.String(20), nullable=False)
  43. gp_value = db.Column(db.Integer, nullable=False)
  44. damage_die = db.Column(db.String(10), nullable=False)
  45. def __repr__(self):
  46. return '<EquipmentRangedWeapon {0}>'.format(self.name)
  47. class EquipmentMeleeWeapon(BaseModel):
  48. __tablename__ = 'eq_melee_wep'
  49. name = db.Column(db.String(50), unique=False, nullable=False)
  50. bucket = db.Column(db.String(20), nullable=False)
  51. gp_value = db.Column(db.Integer, nullable=False)
  52. damage_die = db.Column(db.String(10), nullable=False)
  53. two_handed = db.Column(db.Boolean, nullable=False)
  54. def __repr__(self):
  55. return '<EquipmentMeleeWeapon {0}>'.format(self.name)
  56. class CharacterNPC(BaseModel):
  57. __tablename__ = 'npcs'
  58. name = db.Column(db.String(50), unique=False, nullable=True)
  59. level = db.Column(db.Integer, nullable=False)
  60. alignment = db.Column(db.String(20), unique=False, nullable=False)
  61. hit_points = db.Column(db.Integer, nullable=False)
  62. strength = db.Column(db.Integer, nullable=False)
  63. intelligence = db.Column(db.Integer, nullable=False)
  64. wisdom = db.Column(db.Integer, nullable=False)
  65. dexterity = db.Column(db.Integer, nullable=False)
  66. constitution = db.Column(db.Integer, nullable=False)
  67. charisma = db.Column(db.Integer, nullable=False)
  68. guild_id = db.Column(db.Integer, db.ForeignKey('character_class.id'), nullable=False)
  69. guild = db.relationship('CharacterClass', backref=db.backref('npcs', lazy=True))
  70. melee_id = db.Column(db.Integer, db.ForeignKey('eq_melee_wep.id'), nullable=False)
  71. melee = db.relationship('EquipmentMeleeWeapon')
  72. ranged_id = db.Column(db.Integer, db.ForeignKey('eq_ranged_wep.id'), nullable=True)
  73. ranged = db.relationship('EquipmentRangedWeapon')
  74. armour_id = db.Column(db.Integer, db.ForeignKey('eq_armour.id'), nullable=False)
  75. armour = db.relationship('EquipmentArmour')
  76. def __repr__(self):
  77. return '<CharacterNPC {0}>'.format(self.name)
  78. @staticmethod
  79. def calculate_attr_mod(attr):
  80. mod = 0
  81. if attr <= 3:
  82. mod = -3
  83. elif attr >= 4 and attr <= 5:
  84. mod = -2
  85. elif attr >= 6 and attr <= 8:
  86. mod = -1
  87. elif attr >= 9 and attr <= 12:
  88. mod = 0
  89. elif attr >= 13 and attr <= 15:
  90. mod = 1
  91. elif attr >= 16 and attr <= 16:
  92. mod = 2
  93. elif attr >= 18:
  94. mod = 3
  95. return mod
  96. @property
  97. def roll20_format(self):
  98. npc_dict = {
  99. 'name': self.name,
  100. 'level': self.level,
  101. 'hp': self.hit_points,
  102. 'guild': self.guild.name,
  103. 'alignment': self.alignment,
  104. "attack_throw": self.attack_throw,
  105. 'attributes': {
  106. 'str': self.strength,
  107. 'int': self.intelligence,
  108. 'wis': self.wisdom,
  109. 'dex': self.dexterity,
  110. 'con': self.constitution,
  111. 'chr': self.charisma
  112. },
  113. 'attribute_mods': {
  114. 'str': self.str_mod,
  115. 'int': self.int_mod,
  116. 'wis': self.wis_mod,
  117. 'dex': self.dex_mod,
  118. 'con': self.con_mod,
  119. 'chr': self.chr_mod
  120. },
  121. "saves": {
  122. "pp": self.save_pp,
  123. "pd": self.save_pd,
  124. "bb": self.save_bb,
  125. "sw": self.save_sw,
  126. "sp": self.save_sp
  127. },
  128. 'armour': {
  129. 'name': self.armour.name,
  130. 'value': self.armour.gp_value,
  131. 'ac_mod': self.armour.ac_mod
  132. },
  133. 'melee': {
  134. 'name': self.melee.name,
  135. 'value': self.melee.gp_value,
  136. 'damage': self.melee.damage_die,
  137. 'throw_mod': 0,
  138. 'two_handed': self.melee.two_handed
  139. }
  140. }
  141. if self.ranged:
  142. npc_dict['ranged'] = {
  143. 'name': self.ranged.name,
  144. 'value': self.ranged.gp_value,
  145. 'damage': self.ranged.damage_die,
  146. 'throw_mod': 0
  147. }
  148. return npc_dict
  149. @property
  150. def str(self):
  151. return self.strength
  152. @property
  153. def int(self):
  154. return self.intelligence
  155. @property
  156. def wis(self):
  157. return self.wisdom
  158. @property
  159. def dex(self):
  160. return self.dexterity
  161. @property
  162. def con(self):
  163. return self.constitution
  164. @property
  165. def chr(self):
  166. return self.charisma
  167. @property
  168. def str_mod(self):
  169. return self.calculate_attr_mod(self.strength)
  170. @property
  171. def int_mod(self):
  172. return self.calculate_attr_mod(self.intelligence)
  173. @property
  174. def wis_mod(self):
  175. return self.calculate_attr_mod(self.wisdom)
  176. @property
  177. def dex_mod(self):
  178. return self.calculate_attr_mod(self.dexterity)
  179. @property
  180. def con_mod(self):
  181. return self.calculate_attr_mod(self.constitution)
  182. @property
  183. def chr_mod(self):
  184. return self.calculate_attr_mod(self.charisma)
  185. @property
  186. def current_progression(self):
  187. return ClassLevelProgression.query.filter_by(guild_id=self.guild.id, level=self.level).first()
  188. @property
  189. def attack_throw(self):
  190. return self.current_progression.attack_throw
  191. @property
  192. def save_pp(self):
  193. return self.current_progression.save_petrification_paralysis
  194. @property
  195. def save_pd(self):
  196. return self.current_progression.save_petrification_paralysis
  197. @property
  198. def save_bb(self):
  199. return self.current_progression.save_blast_breath
  200. @property
  201. def save_sw(self):
  202. return self.current_progression.save_staffs_wands
  203. @property
  204. def save_sp(self):
  205. return self.current_progression.save_spells
  206. @property
  207. def hp(self):
  208. return self.hit_points
  209. def update(self, kwargs):
  210. # Allows us to update like a dict, used for inserting attributes zip
  211. self.__dict__.update(kwargs)
  212. admin_models = [CharacterClass, ClassLevelProgression, EquipmentArmour, EquipmentRangedWeapon, EquipmentMeleeWeapon, CharacterNPC]