Merge branch 'canismarko:master' into master

This commit is contained in:
bw-mutley
2021-09-08 11:09:51 -03:00
committed by GitHub
8 changed files with 166 additions and 14 deletions
+1 -1
View File
@@ -1 +1 @@
0.17.0 0.17.1
+2 -7
View File
@@ -136,13 +136,8 @@ class ContentRegistry:
else: else:
attr = found_attrs[0] attr = found_attrs[0]
# Apply weapon/etc. bonuses # Apply weapon/etc. bonuses
if bonus > 0: if bonus > 0 and hasattr(attr, 'improved_version'):
if ( attr = attr.improved_version(bonus)
issubclass(attr, weapons.Weapon)
or issubclass(attr, armor.Shield)
or issubclass(attr, armor.Armor)
):
attr = attr.improved_version(bonus)
return attr return attr
+12
View File
@@ -360,6 +360,18 @@ class InsightfulFighting(Feature):
source = "Rogue (Inquisitive)" source = "Rogue (Inquisitive)"
# Optional class feature from *Tasha's Guide to Everything*
class SteadyAim(Feature):
"""As a bonus action, you give yourself advantage on your next attack
roll on the current turn. You can use this bonus action only if
you haven't moved during this turn, and after you use the bonus
action, your speed is 0 until the end of the current turn.
"""
name = "Steady Aim"
source = "Rogue (3rd level, optional)"
class SteadyEye(Feature): class SteadyEye(Feature):
"""Starting at 9th level, you have advantage on any Wisdom (Perception) or """Starting at 9th level, you have advantage on any Wisdom (Perception) or
Intelligence (Investigation) check if you move no more than half your speed Intelligence (Investigation) check if you move no more than half your speed
+8 -2
View File
@@ -73,11 +73,15 @@ def create_latex_pdf(
module_root = Path(__file__).parent / "modules/" module_root = Path(__file__).parent / "modules/"
module_dirs = [module_root / mdir for mdir in ["DND-5e-LaTeX-Template"]] module_dirs = [module_root / mdir for mdir in ["DND-5e-LaTeX-Template"]]
log.debug(f"Loading additional modules from {module_dirs}.") log.debug(f"Loading additional modules from {module_dirs}.")
environment['TEXINPUTS'] = f".:{':'.join(str(d) for d in module_dirs)}:" + tex_env texinputs = f".:{':'.join(str(d) for d in module_dirs)}:{module_root}:{tex_env}"
environment['TEXINPUTS'] = texinputs
passes = 2 if use_dnd_decorations else 1 passes = 2 if use_dnd_decorations else 1
log.debug(tex_command_line) log.debug(tex_command_line)
log.debug("LaTeX command: %s" % " ".join(tex_command_line)) log.debug("LaTeX command: %s" % " ".join(tex_command_line))
log.debug("LaTeX environ: %s" % environment) log.debug("LaTeX TEXINPUTS: %s" % texinputs)
log.debug("LaTeX environ:")
for key, val in environment.items():
log.debug(" %s: %s" % (key, val))
try: try:
for i in range(passes): for i in range(passes):
result = subprocess.run( result = subprocess.run(
@@ -100,6 +104,8 @@ def create_latex_pdf(
for line in tex_error_msg.split("\n"): for line in tex_error_msg.split("\n"):
log.error(line) log.error(line)
raise exceptions.LatexError(err_msg) raise exceptions.LatexError(err_msg)
finally:
environment['TEXINPUTS'] = tex_env
def tex_error(logfile: Path) -> str: def tex_error(logfile: Path) -> str:
+123
View File
@@ -102,7 +102,29 @@ class RingOfProtection(MagicItem):
item_type = "Ring" item_type = "Ring"
class CloakOfTheBat(MagicItem):
"""While wearing this cloak, you have advantage on Dexterity (Stealth)
checks. In an area of dim light or darkness, you can grip the
edges of the cloak with both hands and use it to fly at a speed of
40 feet. If you ever fail to grip the cloak's edges while flying
in this way, or if you are no longer in dim light or darkness, you
lose this flying speed.
While wearing the cloak in an area of dim light or darkness, you
can use your action to cast polymorph on yourself, transforming
into a bat. While you are in the form of the bat, you retain your
Intelligence, Wisdom, and Charisma scores. The cloak can't be used
this way again until the next dawn.
"""
requires_attunement = True
name = "Cloak of the Bat"
item_type = "Cloak"
class DecanterOfEndlessWater(MagicItem): class DecanterOfEndlessWater(MagicItem):
"""This stoppered flask sloshes when shaken, as if it contains water. The """This stoppered flask sloshes when shaken, as if it contains water. The
decanter weighs 2 pounds. decanter weighs 2 pounds.
@@ -321,3 +343,104 @@ class PearlOfPower(MagicItem):
requires_attunement = True requires_attunement = True
name = "Pearl of Power" name = "Pearl of Power"
class PotionOfHealing(MagicItem):
"""You regain hit points when you drink this potion. The number of hit
points depends on the potions rarity, as shown in the Potions of
Healing table. Whatever its potency, the potions red liquid
glimmers when agitated.
**Potions of Healing**
+-----------------+-----------+-------------+
| Potion of ... | Rarity | HP Regained |
+=================+===========+=============+
|Healing | Common | 2d4 + 2 |
+-----------------+-----------+-------------+
|Greater healing | Uncommon | 4d4 + 4 |
+-----------------+-----------+-------------+
|Superior healing | Rare | 8d4 + 8 |
+-----------------+-----------+-------------+
|Supreme healing | Very rare | 10d4 + 20 |
+-----------------+-----------+-------------+
"""
rarity = "common"
name = "Potion of Healing"
item_type = "Potion"
class PotionOfGreaterHealing(PotionOfHealing):
"""You regain hit points when you drink this potion. The number of hit
points depends on the potions rarity, as shown in the Potions of
Healing table. Whatever its potency, the potions red liquid
glimmers when agitated.
**Potions of Healing**
+-----------------+-----------+-----------------+
| Potion of ... | Rarity | HP Regained |
+=================+===========+=================+
|Healing | Common | ``2d4 + 2`` |
+-----------------+-----------+-----------------+
|Greater healing | Uncommon | ``4d4 + 4`` |
+-----------------+-----------+-----------------+
|Superior healing | Rare | ``8d4 + 8`` |
+-----------------+-----------+-----------------+
|Supreme healing | Very rare | ``10d4 + 20`` |
+-----------------+-----------+-----------------+
"""
name = "Potion of Greater Healing"
rarity = "uncommon"
class PotionOfSuperiorHealing(PotionOfHealing):
"""You regain hit points when you drink this potion. The number of hit
points depends on the potions rarity, as shown in the Potions of
Healing table. Whatever its potency, the potions red liquid
glimmers when agitated.
**Potions of Healing**
+-----------------+-----------+-------------+
| Potion of ... | Rarity | HP Regained |
+=================+===========+=============+
|Healing | Common | 2d4 + 2 |
+-----------------+-----------+-------------+
|Greater healing | Uncommon | 4d4 + 4 |
+-----------------+-----------+-------------+
|Superior healing | Rare | 8d4 + 8 |
+-----------------+-----------+-------------+
|Supreme healing | Very rare | 10d4 + 20 |
+-----------------+-----------+-------------+
"""
name = "Potion of Superior Healing"
rarity = "rare"
class PotionOfSupremeHealing(PotionOfHealing):
"""You regain hit points when you drink this potion. The number of hit
points depends on the potions rarity, as shown in the Potions of
Healing table. Whatever its potency, the potions red liquid
glimmers when agitated.
**Potions of Healing**
+-----------------+-----------+-------------+
| Potion of ... | Rarity | HP Regained |
+=================+===========+=============+
|Healing | Common | 2d4 + 2 |
+-----------------+-----------+-------------+
|Greater healing | Uncommon | 4d4 + 4 |
+-----------------+-----------+-------------+
|Superior healing | Rare | 8d4 + 8 |
+-----------------+-----------+-------------+
|Supreme healing | Very rare | 10d4 + 20 |
+-----------------+-----------+-------------+
"""
name = "Potion of Supreme Healing"
rarity = "very rare"
-1
View File
@@ -114,7 +114,6 @@ def create_random_tables_content(
) -> str: ) -> str:
template = jinja_env.get_template(f"random_tables_template.{suffix}") template = jinja_env.get_template(f"random_tables_template.{suffix}")
return template.render( return template.render(
conjure_animals=True,
tables=tables, tables=tables,
use_dnd_decorations=use_dnd_decorations, use_dnd_decorations=use_dnd_decorations,
) )
+18 -1
View File
@@ -2,7 +2,7 @@ from unittest import TestCase
from dungeonsheets.content_registry import ContentRegistry from dungeonsheets.content_registry import ContentRegistry
from dungeonsheets import monsters from dungeonsheets import monsters, weapons
class TestContentRegistry(TestCase): class TestContentRegistry(TestCase):
@@ -62,3 +62,20 @@ class TestContentRegistry(TestCase):
# Direct access # Direct access
self.assertEqual(creg.findattr("my_attr", valid_classes=[int]), test_module.my_attr) self.assertEqual(creg.findattr("my_attr", valid_classes=[int]), test_module.my_attr)
def test_findattr_magic_weapon(self):
creg = ContentRegistry()
creg.add_module(weapons)
# First test with a non-magical weapon
shortsword = creg.findattr("shortsword")
self.assertIs(shortsword, weapons.Shortsword)
# Now test with a magical weapon
magic_shortsword = creg.findattr("shortsword + 1")
self.assertTrue(issubclass(magic_shortsword, weapons.Shortsword),
"Improved version is not subclass of base.")
self.assertEqual(magic_shortsword.attack_bonus, 1)
self.assertEqual(magic_shortsword.damage_bonus, 1)
# Make sure some other item that can't be "improved" still works
creg = ContentRegistry()
creg.add_module(monsters)
lich = creg.findattr("lich+1")
self.assertIs(lich, monsters.Lich)
+2 -2
View File
@@ -2,7 +2,7 @@ import unittest
import os import os
from pathlib import Path from pathlib import Path
from dungeonsheets import make_sheets, character, monsters from dungeonsheets import make_sheets, character, monsters, random_tables
EG_DIR = Path(__file__).parent.parent.resolve() / "examples" EG_DIR = Path(__file__).parent.parent.resolve() / "examples"
@@ -283,7 +283,7 @@ class TexCreatorTestCase(unittest.TestCase):
def test_random_tables_tex(self): def test_random_tables_tex(self):
tex = make_sheets.create_random_tables_content( tex = make_sheets.create_random_tables_content(
tables=[random_tables.ConjureAnimals],
suffix="tex", suffix="tex",
conjure_animals=True,
) )
self.assertIn(r"\subsection*{Conjure Animals}", tex) self.assertIn(r"\subsection*{Conjure Animals}", tex)