Source code for DnD_5e.features

import inspect
from DnD_5e import armor, armory
[docs] class Feature: """ This class represents features (class features, race features, background features etc.) that change a Combatant's stats or how a Combatant can act """
[docs] @classmethod def get_ol_methods(cls): """ :return: the methods that this class overloads :rtype: list of name, value tuples (name is a str for the name of the function, value is the method object) """ methods = inspect.getmembers(cls, lambda x: inspect.ismethod(x) and x.__name__ != 'get_ol_methods') return methods
[docs] class UnarmoredDefenseBarbarian(Feature):
[docs] @classmethod def get_unarmored_ac(cls, src): """ :param src: the Combatant this Feature applies to :return: unarmored ac (10 + dex + con) """ try: return 10 + src.get_dexterity() + src.get_constitution() except AttributeError: raise ValueError("Tried to use Barbarian Unarmored Defense on something that is not a Combatant")
[docs] class FastMovementBarbarian(Feature):
[docs] @classmethod def get_speed(cls, src): """ :param src: the Combatant this Feature applies to :return: speed + 10 (when src isn't wearing heavy armor) """ # pylint: disable=protected-access if inspect.isclass(src.get_armor()) and issubclass(src.get_armor(), armor.HeavyArmor): return src._speed # TODO: use accessor method instead of instance variable, but avoid infinite recursion return src._speed + 10
[docs] class ArcheryFightingStyle(Feature):
[docs] @classmethod def get_weapon_attack_mod(cls, src, weapon): # pylint: disable=unused-argument """ Get modifiers for weapon attacks. **Update method**: returns the difference from what src would get normally (i.e., return 2 for ranged_attack_mod to say ranged_attack_mod is 2 greater than normal) :param src: the Combatant this Feature applies to :param weapon: the weapon to look at :type weapon: :py:class:`Weapon` :return: attack modifier :rtype: int """ if isinstance(weapon, armory.RangedWeapon): return 2 return 0
[docs] class DefenseFightingStyle(Feature):
[docs] @classmethod def get_ac(cls, src): """ Get ac for the combatant. **Update method**: returns the difference from what src would get normally (i.e., return 1 to say ac is 1 greater than normal) :param src: the Combatant this Feature applies to :return: ac :rtype: positive integer """ if src.get_armor() is not None: return 1 return 0
[docs] class UnarmoredDefenseMonk(Feature):
[docs] @classmethod def get_unarmored_ac(cls, src): """ :param src: the Combatant this Feature applies to :return: unarmored ac (10 + dex + con) """ try: return 10 + src.get_dexterity() + src.get_wisdom() except AttributeError: raise ValueError("Tried to use Monk Unarmored Defense on something that is not a Combatant")
[docs] class DraconicResilience(Feature):
[docs] @classmethod def get_unarmored_ac(cls, src): """ Note: this doesn't apply the hit point maximum effects. :param src: the Combatant this Feature applies to :return: unarmored ac (10 + dex + con) """ try: return 13 + src.get_dexterity() except AttributeError: raise ValueError("Tried to use Draconic Resilience on something that is not a Combatant")