mirror of
https://github.com/Threnklyn/dungeon-sheets.git
synced 2026-05-19 04:33:26 +02:00
Merge pull request #71 from 94d90b08-c4ef-416c-bf7b-b6c5b7275e6a/master
hp_max basic auto-calculation, boolean inspiration
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
@@ -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?
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user