diff --git a/dungeonsheets/character.py b/dungeonsheets/character.py index ba466ed..7976186 100644 --- a/dungeonsheets/character.py +++ b/dungeonsheets/character.py @@ -21,7 +21,7 @@ def read(fname): return open(os.path.join(os.path.dirname(__file__), fname)).read() -__version__ = read('../VERSION') +__version__ = read('../VERSION').strip() dice_re = re.compile('(\d+)d(\d+)') @@ -132,7 +132,7 @@ class Character(): """Takes a bunch of attrs and passes them to ``set_attrs``""" self.weapons = [] # make sure class, race, background are set first - my_classes = attrs.pop('classes', ['Char Class']) + my_classes = attrs.pop('classes', []) my_levels = attrs.pop('levels', []) my_subclasses = attrs.pop('subclasses', []) # backwards compatability @@ -681,7 +681,8 @@ class Character(): from .make_sheets import make_sheet if filename.endswith('.pdf'): filename = filename.replace('pdf', 'py') - make_sheet(filename, char=self, flatten=kwargs.get('flatten', True)) + make_sheet(filename, character=self, + flatten=kwargs.get('flatten', True)) def parse_classes(classes_list=[], levels=[], subclasses=[], @@ -764,14 +765,83 @@ def read_character_file(filename): # Add backwards compatability for tests -class Druid(Character): +class Barbarian(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Barbarian'] + attrs['levels'] = [level] + super().__init__(**attrs) + +class Bard(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Bard'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Cleric(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Cleric'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Druid(Character): def __init__(self, level=1, **attrs): attrs['classes'] = ['Druid'] attrs['levels'] = [level] super().__init__(**attrs) +class Fighter(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Fighter'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Monk(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Monk'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Paladin(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Paladin'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Ranger(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Ranger'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Rogue(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Rogue'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Sorceror(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Sorceror'] + attrs['levels'] = [level] + super().__init__(**attrs) + + +class Warlock(Character): + def __init__(self, level=1, **attrs): + attrs['classes'] = ['Warlock'] + attrs['levels'] = [level] + super().__init__(**attrs) + + class Wizard(Character): def __init__(self, level=1, **attrs): diff --git a/dungeonsheets/weapons.py b/dungeonsheets/weapons.py index 6b83110..c5041e9 100644 --- a/dungeonsheets/weapons.py +++ b/dungeonsheets/weapons.py @@ -17,7 +17,7 @@ class Weapon(): def damage(self): dam_str = str(self.base_damage) if self.bonus_damage != 0: - dam_str += ' ' + mod_str(self.bonus_damage) + dam_str += mod_str(self.bonus_damage) return dam_str @property diff --git a/tests/test_features.py b/tests/test_features.py new file mode 100644 index 0000000..19df11e --- /dev/null +++ b/tests/test_features.py @@ -0,0 +1,16 @@ +#!/usr/bin/env python + +from unittest import TestCase + +from dungeonsheets.features import create_feature, Feature + + +class TestFeatures(TestCase): + """Tests for features and feature-related activities.""" + + def test_create_feature(self): + NewFeature = create_feature(name="Hello world") + self.assertTrue(issubclass(NewFeature, Feature)) + self.assertEqual(NewFeature.name, 'Hello world') + feature = NewFeature() + print(feature, feature.__class__, type(feature)) diff --git a/tests/test_multiclass.py b/tests/test_multiclass.py new file mode 100644 index 0000000..2bee4a8 --- /dev/null +++ b/tests/test_multiclass.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python + +from unittest import TestCase +import warnings + +from dungeonsheets import race, monsters, exceptions, spells +from dungeonsheets.character import Character +from dungeonsheets.weapons import Weapon, Shortsword +from dungeonsheets.armor import Armor, LeatherArmor, Shield + + +class TestMulticlass(TestCase): + """ + Tests for Multiclass character. + """ + def test_constructor(self): + char = Character(name='Multiclass', + classes=['wizard', 'fighter'], + levels=[5, 4]) + + def test_level(self): + char = Character(name='Multiclass', + classes=['wizard', 'fighter'], + levels=[5, 4]) + self.assertEqual(char.level, 9) + + def test_spellcasting(self): + char = Character(name='Multiclass', + classes=['wizard', 'fighter'], + levels=[5, 4]) + self.assertEqual(len(char.spellcasting_classes), 1) + char = Character(name='Multiclass', + classes=['wizard', 'fighter'], + subclasses=[None, 'Eldritch Knight'], + levels=[5, 4]) + self.assertEqual(len(char.spellcasting_classes), 2) + # equivalent spellcasting level: 6 + self.assertEqual(char.spell_slots(spell_level=1), 4) + self.assertEqual(char.spell_slots(spell_level=2), 3) + self.assertEqual(char.spell_slots(spell_level=3), 3) + self.assertEqual(char.spell_slots(spell_level=4), 0) + + def test_proficiencies(self): + char1 = Character(name='Multiclass', + classes=['wizard', 'fighter'], + levels=[5, 4]) + for svt in ('intelligence', 'wisdom'): + self.assertIn(svt, char1.saving_throw_proficiencies) + char2 = Character(name='Multiclass', + classes=['wizard', 'rogue'], + levels=[5, 4]) + char3 = Character(name='Multiclass', + classes=['rogue', 'wizard'], + levels=[4, 5]) + sword = Shortsword() + self.assertTrue(char1.is_proficient(sword)) + # multiclassing into Rogue doesn't give simple weapon proficiency + self.assertFalse(char2.is_proficient(sword)) + self.assertTrue(char3.is_proficient(sword)) + diff --git a/tests/test_weapon.py b/tests/test_weapon.py index 9017751..881f7cb 100644 --- a/tests/test_weapon.py +++ b/tests/test_weapon.py @@ -2,6 +2,7 @@ import unittest from dungeonsheets.weapons import Weapon + class WeaponTestCase(unittest.TestCase): def test_weapon_damage(self): weapon = Weapon() @@ -9,4 +10,4 @@ class WeaponTestCase(unittest.TestCase): self.assertEqual(weapon.damage, '1d6') # Now add some bonus damage weapon.bonus_damage = 2 - self.assertEqual(weapon.damage, '1d6 +2') + self.assertEqual(weapon.damage, '1d6+2')