reorganized spells by name, and added directory for features for each class"

This commit is contained in:
Ben Cook
2018-12-20 09:09:38 -05:00
parent 0ed7262fc8
commit b93b1ac6d7
52 changed files with 5768 additions and 5458 deletions
+16
View File
@@ -0,0 +1,16 @@
from .features import Feature, create_feature
from .barbarian import *
from .bard import *
from .cleric import *
from .druid import *
from .fighter import *
from .monk import *
from .paladin import *
from .ranger import *
from .rogue import *
from .sorceror import *
from .warlock import *
from .wizard import *
from .races import *
from .backgrounds import *
View File
View File
View File
View File
+80
View File
@@ -0,0 +1,80 @@
from .. import weapons
def create_feature(**params):
"""Create a new subclass of ``Feature`` with given default parameters.
Useful for features that haven't been entered into the ``features.py``
file yet.
Parameters
----------
params : optional
Saved as attributes of the new class.
Returns
-------
NewFeature
New feature class, subclass of ``Feature``, with given params.
"""
NewFeature = type('UnknownFeature', (Feature,), params)
return NewFeature
class Feature():
"""
Provide full text of rules in documentation
"""
name = "Generic Feature"
source = '' # race, class, background, etc.
needs_implementation = False # Set to True if need to find way to compute stats
def __eq__(self, other):
return (self.name == other.name) and (self.source == other.source)
def __hash__(self):
return 0
def __str__(self):
return self.name
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""
Updates weapon based on the Feature property
Parameters
----------
weapon
The weapon to be tested for special bonuses
kwargs
Any other key-word arguments the function may require
Returns
-------
weapon
Updated weapon (perhaps changed damage bonus, etc.)
"""
return weapon
def AC_func(self, char, **kwargs):
"""
Return the alternative AC from having this feat
The character will take max AC from all available feats / standard AC,
so the default is to output very low AC
Parameters
----------
char
Character object, to check for necessary abilities, etc.
kwargs
Any other key-word arguments the function may require
Returns
-------
AC : integer armor class from this feature
"""
return -100
View File
+77
View File
@@ -0,0 +1,77 @@
from .features import Feature
from .. import (weapons, armor)
class UnarmoredDefense(Feature):
"""Beginning at 1st level, while you are wearing no armor and not wearing a
shield, your AC equals 10 + your Dexterity modifier + your Wisdom modifier.
"""
name = "Unarmored Defense"
source = 'Monk'
def AC_func(self, char):
no_armor = ((char.armor is None)
or (isinstance(char.armor, armor.NoAmor)))
no_shield = ((char.shield is None)
or (isinstance(char.shield, armor.NoShield)))
if no_armor and no_shield:
return 10 + char.dexterity.modifier + char.wisdom.modifier
else:
return -100
class MartialArts(Feature):
"""At 1st level, your practice of martial arts gives you mastery of combat
styles that use unarmed strikes and monk weapons, which are shortswords and
any simple melee weapons that dont have the two-handed or heavy
property. You gain the following benefits while you are unarmed or wielding
only monk weapons and you arent wearing armor or wielding a shield:
-- You can use Dexterity instead of Strength for the attack and damage rolls
of your unarmed strikes and monk weapons.
-- You can roll a d4 in place of the normal damage of your unarmed strike or
monk weapon. This die changes as you gain monk levels, as shown in the
Martial Arts column of the Monk table.
-- When you use the Attack action with an unarmed strike or a monk weapon on
your turn, you can make one unarmed strike as a bonus action. For example,
if you take the Attack action and attack with a quarter- staff, you can
also make an unarmed strike as a bonus action, assuming you haven't already
taken a bonus action this turn.
Certain monasteries use specializepd forms of the monk weapons. For
example, you might use a club that is two lengths of w ood connected by a
short chain (called a nunchaku) or a sickle with a shorter, straighter
blade (called a kama). Whatever name you use for a monk weapon, you can use
the game statistics provided for
"""
name = "Martial Arts"
source = 'Monk'
die_by_level = {1: 'd4', 2: 'd4', 3: 'd4', 4: 'd4',
5: 'd6', 6: 'd6', 7: 'd6', 8: 'd6',
9: 'd6', 10: 'd6', 11: 'd8', 12: 'd8',
13: 'd8', 14: 'd8', 15: 'd8', 16: 'd8',
17: 'd10', 18: 'd10', 19: 'd10', 20: 'd10'}
level = 1
def weapon_func(self, weapon: weapons.Weapon, char=None, **kwargs):
"""
Update increasing damage dice and DEX mod of Monk weapons
"""
is_monk_weapon = any([isinstance(weapon, w)
for w in weapons.monk_weapons])
if not is_monk_weapon:
return weapon
if char is None:
return weapon
# check if new damage is better than default
new_die = int(self.die_by_level[self.level].strip('d'))
if new_die > int(weapon.base_damage.split('d')[-1]):
weapon.base_damage = '1d' + str(new_die)
weapon.is_finesse = True
return weapon
View File
View File
+86
View File
@@ -0,0 +1,86 @@
from .features import Feature
from .. import (weapons, armor)
def select_ranger_fighting_style(feature_choices=[]):
lower_choices = [fc for fc in map(str.lower, feature_choices)]
if 'archery' in lower_choices:
return Archery()
elif 'defense' in lower_choices:
return Defense()
elif 'dueling' in lower_choices:
return Dueling()
elif 'two-weapon fighting' in lower_choices:
return TwoWeaponFighting()
else:
return RangerFightingStyle()
class RangerFightingStyle(Feature):
"""
Select a Fighting Style by choosing in feature_choices:
archery
defense
dueling
two-weapon fighting
"""
name = "Fighting Style (Select One)"
source = "Ranger"
class Archery(Feature):
"""
You gain a +2 bonus to attack rolls you make
with ranged weapons.
"""
name = "Fighting Style (Archery)"
source = "Ranger"
def weapon_func(self, weapon: weapons.Weapon, **kwargs):
"""
+2 attack roll bonus if weapon is ranged
"""
if weapon.is_ranged:
weapon.attack_bonus += 2
return weapon
class Defense(Feature):
"""
While you are wearing armor, you gain a +1 bonus to AC.
"""
name = "Fighting Style (Defense)"
source = "Ranger"
def AC_func(self, char, **kwargs):
"""
Apply a +1 bonus if wearing armor
"""
if (char.armor is None) or (isinstance(char.armor, armor.NoArmor)):
return char.default_AC
else:
return char.default_AC + 1
class Dueling(Feature):
"""When you are wielding a melee weapon in one hand and no other weapons, you
gain a +2 bonus to damage rolls with that weapon.
"""
name = "Fighting Style (Dueling)"
source = "Ranger"
needs_implementation = True
class TwoWeaponFighting(Feature):
"""When you engage in two-weapon fighting, you can add your ability modifier
to the damage of the second attack.
"""
name = "Fighting Style (Two-Weapon Fighting)"
source = "Ranger"
needs_implementation = True
View File
View File
View File
View File