Merge pull request #71 from 94d90b08-c4ef-416c-bf7b-b6c5b7275e6a/master

hp_max basic auto-calculation, boolean inspiration
This commit is contained in:
Mark Wolf
2020-05-19 10:55:26 -05:00
committed by GitHub
6 changed files with 48 additions and 14 deletions
+2 -1
View File
@@ -1,6 +1,7 @@
install:
python setup.py install
@echo "\n\n================="
@echo ""
@echo "================="
@echo "For optimal performance we highly recommend installing PDFTK: https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/"
@echo "If installing on OSX >= 10.11, see here: https://stackoverflow.com/questions/32505951/pdftk-server-on-os-x-10-11/33248310#33248310"
+26 -4
View File
@@ -71,7 +71,7 @@ class Character():
_background = None
xp = 0
# Hit points
hp_max = 10
hp_max = None
# Base stats (ability scores)
strength = Ability()
dexterity = Ability()
@@ -82,7 +82,7 @@ class Character():
armor_class = ArmorClass()
initiative = Initiative()
speed = Speed()
inspiration = 0
inspiration = False
_saving_throw_proficiencies = tuple() # use to overwrite class proficiencies
other_weapon_proficiencies = tuple() # add to class/race proficiencies
skill_proficiencies = list()
@@ -161,6 +161,7 @@ class Character():
self.background = attrs.pop('background', None)
# parse all other attributes
self.set_attrs(**attrs)
self.__set_max_hp(attrs.get('hp_max', None))
def clear(self):
# reset class-definied items
@@ -317,6 +318,25 @@ class Character():
else:
return None
def __set_max_hp(self, hp_max):
"""
Set maximum HP based on value in charlist py or calc from classes
"""
if hp_max:
assert isinstance(hp_max, int)
self.hp_max = hp_max
else:
const_mod = self.constitution.modifier
level_one_hp = self.primary_class.hit_dice_faces + const_mod
self.hp_max = level_one_hp
for char_cls in self.class_list:
hp_per_lvl = char_cls.hit_dice_faces/2 + 1 + const_mod
levels = char_cls.level
if char_cls == self.primary_class:
levels -= 1
assert levels >= 0
self.hp_max += int(hp_per_lvl * levels)
@property
def weapon_proficiencies(self):
wp = set(self.other_weapon_proficiencies)
@@ -451,8 +471,10 @@ class Character():
return sorted(tuple(spells), key=(lambda x: (x.name)))
def set_attrs(self, **attrs):
"""Bulk setting of attributes. Useful for loading a character from a
dictionary."""
"""
Bulk setting of attributes
Useful for loading a character from a dictionary
"""
for attr, val in attrs.items():
if attr == 'dungeonsheets_version':
pass # Maybe we'll verify this later?
+1 -1
View File
@@ -20,7 +20,7 @@ alignment = "{{ char.alignment }}"
xp = {{ char.xp }}
hp_max = {{ char.hp_max }}
inspiration = {{ char.inspiration }} # integer inspiration value
inspiration = {{ char.inspiration }} # boolean inspiration value
# Ability Scores
strength = {{ char.strength.value }}
+1 -1
View File
@@ -23,7 +23,7 @@ alignment = "{{ char.alignment }}"
xp = {{ char.xp }}
hp_max = {{ char.hp_max }}
inspiration = {{ char.inspiration }} # integer inspiration value
inspiration = {{ char.inspiration }} # boolean inspiration value
# Ability Scores
strength = {{ char.strength.value }}
+8 -6
View File
@@ -289,7 +289,7 @@ def create_character_pdf(character, basename, flatten=False):
'Race ': str(character.race),
'Alignment': character.alignment,
'XP': str(character.xp),
'Inspiration': str(character.inspiration),
'Inspiration': str('Yes' if character.inspiration else 'No'),
# Abilities
'ProfBonus': mod_str(character.proficiency_bonus),
'STRmod': str(character.strength.value),
@@ -400,11 +400,13 @@ def create_character_pdf(character, basename, flatten=False):
fields[atk_field] = '{:+d}'.format(weapon.attack_modifier)
fields[dmg_field] = f'{weapon.damage}/{weapon.damage_type}'
# Other attack information
attack_str = f'Armor: {character.armor}'
attack_str += '\n \n'
attack_str += f'Shield: {character.shield}'
attack_str += '\n \n'
attack_str += character.attacks_and_spellcasting
attack = []
if character.armor:
attack.append(f'Armor: {character.armor}')
if character.shield:
attack.append(f'Shield: {character.shield}')
attack.append(character.attacks_and_spellcasting)
attack_str = '\n\n'.join(attack)
fields['AttacksSpellcasting'] = text_box(attack_str)
# Other proficiencies and languages
prof_text = "Proficiencies:\n" + text_box(character.proficiencies_text)
Regular → Executable
+10 -1
View File
@@ -21,7 +21,11 @@ class TestCharacter(TestCase):
char.level = 2
char.hit_dice_faces = 10
self.assertEqual(char.hit_dice, '2d10')
def test_max_hp(self):
char = Wizard(level=3, constitution=12)
self.assertEqual(char.hp_max, 17)
def test_set_attrs(self):
char = Character()
char.set_attrs(name='Inara')
@@ -37,6 +41,11 @@ class TestCharacter(TestCase):
# Check that race gets set to an object
char.set_attrs(race='high elf')
self.assertIsInstance(char.race, race.HighElf)
# Check inspiration works
char.set_attrs(inspiration=True)
self.assertTrue(char.inspiration)
char.set_attrs(inspiration=False)
self.assertFalse(char.inspiration)
def test_wield_weapon(self):
char = Character()