mirror of
https://github.com/Threnklyn/dungeon-sheets.git
synced 2026-06-06 21:01:26 +02:00
_resolve_mechanic no longer accepts a *module* argument since it uses the content registry.
This commit is contained in:
+17
-15
@@ -69,32 +69,39 @@ multiclass_spellslots_by_level = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _resolve_mechanic(mechanic, module, SuperClass, warning_message=None):
|
def _resolve_mechanic(mechanic, SuperClass, warning_message=None):
|
||||||
"""Take a raw entry in a character sheet and turn it into a usable object.
|
"""Take a raw entry in a character sheet and turn it into a usable object.
|
||||||
|
|
||||||
Eg: spells can be defined in many ways. This function accepts all
|
Eg: spells can be defined in many ways. This function accepts all
|
||||||
of those options and returns an actual *Spell* class that can be
|
of those options and returns an actual *Spell* class that can be
|
||||||
used by a character::
|
used by a character::
|
||||||
|
|
||||||
|
>>> _resolve_mechanic("mage_hand", SuperClass=spells.Spell)
|
||||||
|
|
||||||
|
>>> _resolve_mechanic("mage_hand", SuperClass=None)
|
||||||
|
|
||||||
>>> from dungeonsheets import spells
|
>>> from dungeonsheets import spells
|
||||||
>>> _resolve_mechanic("mage_hand", spells, None)
|
|
||||||
>>> class MySpell(spells.Spell): pass
|
>>> class MySpell(spells.Spell): pass
|
||||||
>>> _resolve_mechanic(MySpell, None, spells.Spell)
|
>>> _resolve_mechanic(MySpell, SuperClass=spells.Spell)
|
||||||
>>> _resolve_mechanic("hocus pocus", spells, None)
|
|
||||||
|
>>> _resolve_mechanic("hocus pocus", SuperClass=spells.Spell)
|
||||||
|
|
||||||
The acceptable entries for *mechanic*, in priority order, are:
|
The acceptable entries for *mechanic*, in priority order, are:
|
||||||
1. A subclass of *SuperClass*
|
1. A subclass of *SuperClass*
|
||||||
2. A string with the name of a defined spell in *module*
|
2. A string with the name of defined content
|
||||||
3. The name of an unknown spell (creates generic object using *factory*)
|
3. The name of an unknown spell (creates generic object using *factory*)
|
||||||
|
|
||||||
|
*SuperClass* can be ``None`` to match any class, however this will
|
||||||
|
raise an exception if more than one content type has this
|
||||||
|
name. For example, "shield" can refer to both the armor or the
|
||||||
|
spell, so ``_resolve_mechanic("shield")`` will raise an exception.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
==========
|
==========
|
||||||
mechanic : str, type
|
mechanic : str, type
|
||||||
The thing to be resolved, either a string with the name of the
|
The thing to be resolved, either a string with the name of the
|
||||||
mechanic, or a subclass of *ParentClass* describing the
|
mechanic, or a subclass of *ParentClass* describing the
|
||||||
mechanic.
|
mechanic.
|
||||||
module : module
|
|
||||||
A python module in which to look for the defined string in *name*.
|
|
||||||
SuperClass : type
|
SuperClass : type
|
||||||
Class to determine whether *mechanic* should just be allowed
|
Class to determine whether *mechanic* should just be allowed
|
||||||
through as is.
|
through as is.
|
||||||
@@ -120,7 +127,8 @@ def _resolve_mechanic(mechanic, module, SuperClass, warning_message=None):
|
|||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
# Retrieve pre-defined mechanic
|
# Retrieve pre-defined mechanic
|
||||||
Mechanic = find_content(mechanic, valid_classes=[SuperClass])
|
valid_classes = [SuperClass] if SuperClass is not None else []
|
||||||
|
Mechanic = find_content(mechanic, valid_classes=valid_classes)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
# No pre-defined mechanic available
|
# No pre-defined mechanic available
|
||||||
if warning_message is not None:
|
if warning_message is not None:
|
||||||
@@ -618,7 +626,6 @@ class Character(Entity):
|
|||||||
)
|
)
|
||||||
ThisMagicItem = _resolve_mechanic(
|
ThisMagicItem = _resolve_mechanic(
|
||||||
mechanic=mitem,
|
mechanic=mitem,
|
||||||
module=magic_items,
|
|
||||||
SuperClass=magic_items.MagicItem,
|
SuperClass=magic_items.MagicItem,
|
||||||
warning_message=msg,
|
warning_message=msg,
|
||||||
)
|
)
|
||||||
@@ -627,7 +634,7 @@ class Character(Entity):
|
|||||||
self.other_weapon_proficiencies = ()
|
self.other_weapon_proficiencies = ()
|
||||||
msg = 'Magic Item "{}" not defined. Please add it to ``weapons.py``'
|
msg = 'Magic Item "{}" not defined. Please add it to ``weapons.py``'
|
||||||
wps = set(
|
wps = set(
|
||||||
[_resolve_mechanic(w, weapons, weapons.Weapon, msg) for w in val]
|
[_resolve_mechanic(w, SuperClass=weapons.Weapon, warning_message=msg) for w in val]
|
||||||
)
|
)
|
||||||
wps -= set(self.weapon_proficiencies)
|
wps -= set(self.weapon_proficiencies)
|
||||||
self.other_weapon_proficiencies = list(wps)
|
self.other_weapon_proficiencies = list(wps)
|
||||||
@@ -646,7 +653,6 @@ class Character(Entity):
|
|||||||
msg = 'Feature "{}" not defined. Please add it to ``features.py``'
|
msg = 'Feature "{}" not defined. Please add it to ``features.py``'
|
||||||
ThisFeature = _resolve_mechanic(
|
ThisFeature = _resolve_mechanic(
|
||||||
mechanic=f,
|
mechanic=f,
|
||||||
module=features,
|
|
||||||
SuperClass=features.Feature,
|
SuperClass=features.Feature,
|
||||||
warning_message=msg,
|
warning_message=msg,
|
||||||
)
|
)
|
||||||
@@ -659,7 +665,6 @@ class Character(Entity):
|
|||||||
msg = 'Spell "{}" not defined. Please add it to ``spells.py``'
|
msg = 'Spell "{}" not defined. Please add it to ``spells.py``'
|
||||||
ThisSpell = _resolve_mechanic(
|
ThisSpell = _resolve_mechanic(
|
||||||
mechanic=spell_name,
|
mechanic=spell_name,
|
||||||
module=spells,
|
|
||||||
SuperClass=spells.Spell,
|
SuperClass=spells.Spell,
|
||||||
warning_message=msg,
|
warning_message=msg,
|
||||||
)
|
)
|
||||||
@@ -683,7 +688,6 @@ class Character(Entity):
|
|||||||
)
|
)
|
||||||
ThisInfusion = _resolve_mechanic(
|
ThisInfusion = _resolve_mechanic(
|
||||||
mechanic=infusion_name,
|
mechanic=infusion_name,
|
||||||
module=infusions,
|
|
||||||
SuperClass=infusions.Infusion,
|
SuperClass=infusions.Infusion,
|
||||||
warning_message=msg,
|
warning_message=msg,
|
||||||
)
|
)
|
||||||
@@ -793,7 +797,6 @@ class Character(Entity):
|
|||||||
msg = 'Unnown armor "{}". Please add it to ``armor.py``.'
|
msg = 'Unnown armor "{}". Please add it to ``armor.py``.'
|
||||||
NewArmor = _resolve_mechanic(
|
NewArmor = _resolve_mechanic(
|
||||||
mechanic=new_armor,
|
mechanic=new_armor,
|
||||||
module=armor,
|
|
||||||
SuperClass=armor.Armor,
|
SuperClass=armor.Armor,
|
||||||
warning_message=msg,
|
warning_message=msg,
|
||||||
)
|
)
|
||||||
@@ -834,7 +837,6 @@ class Character(Entity):
|
|||||||
msg = 'Unknown weapon "{}". Please add it to ``weapons.py``.'
|
msg = 'Unknown weapon "{}". Please add it to ``weapons.py``.'
|
||||||
ThisWeapon = _resolve_mechanic(
|
ThisWeapon = _resolve_mechanic(
|
||||||
mechanic=weapon,
|
mechanic=weapon,
|
||||||
module=weapons,
|
|
||||||
SuperClass=weapons.Weapon,
|
SuperClass=weapons.Weapon,
|
||||||
warning_message=msg,
|
warning_message=msg,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from functools import lru_cache
|
|||||||
import importlib.util
|
import importlib.util
|
||||||
from typing import Union, List, Optional
|
from typing import Union, List, Optional
|
||||||
|
|
||||||
from dungeonsheets import weapons, monsters, race, background, armor, spells, infusions, magic_items
|
from dungeonsheets import weapons, monsters, race, background, armor, spells, infusions, magic_items, features
|
||||||
|
|
||||||
|
|
||||||
class ContentRegistry():
|
class ContentRegistry():
|
||||||
@@ -80,6 +80,7 @@ default_content_registry.add_module(armor)
|
|||||||
default_content_registry.add_module(spells)
|
default_content_registry.add_module(spells)
|
||||||
default_content_registry.add_module(infusions)
|
default_content_registry.add_module(infusions)
|
||||||
default_content_registry.add_module(magic_items)
|
default_content_registry.add_module(magic_items)
|
||||||
|
default_content_registry.add_module(features)
|
||||||
|
|
||||||
|
|
||||||
def find_content(name: str, valid_classes: Optional[List]):
|
def find_content(name: str, valid_classes: Optional[List]):
|
||||||
@@ -100,7 +101,7 @@ def find_content(name: str, valid_classes: Optional[List]):
|
|||||||
return default_content_registry.findattr(name, valid_classes=valid_classes)
|
return default_content_registry.findattr(name, valid_classes=valid_classes)
|
||||||
|
|
||||||
|
|
||||||
@lru_cache
|
@lru_cache()
|
||||||
def import_homebrew(filepath: Union[str, Path]):
|
def import_homebrew(filepath: Union[str, Path]):
|
||||||
"""Import a module file containing homebrew content.
|
"""Import a module file containing homebrew content.
|
||||||
|
|
||||||
|
|||||||
@@ -79,24 +79,23 @@ class TestCharacter(TestCase):
|
|||||||
self.assertIsInstance(char.infusions[0], infusions.Infusion)
|
self.assertIsInstance(char.infusions[0], infusions.Infusion)
|
||||||
self.assertEqual(char.infusions[0].name, "Spam Infusion")
|
self.assertEqual(char.infusions[0].name, "Spam Infusion")
|
||||||
|
|
||||||
@expectedFailure
|
|
||||||
def test_resolve_mechanic(self):
|
def test_resolve_mechanic(self):
|
||||||
# Test a well defined mechanic
|
# Test a well defined mechanic
|
||||||
NewSpell = _resolve_mechanic("mage_hand", spells, None)
|
NewSpell = _resolve_mechanic("mage_hand", None)
|
||||||
self.assertTrue(issubclass(NewSpell, spells.Spell))
|
self.assertTrue(issubclass(NewSpell, spells.Spell))
|
||||||
|
|
||||||
# Test an unknown mechanic
|
# Test an unknown mechanic
|
||||||
def new_spell(**params):
|
def new_spell(**params):
|
||||||
return spells.Spell
|
return spells.Spell
|
||||||
|
|
||||||
NewSpell = _resolve_mechanic("hocus_pocus", spells, spells.Spell)
|
NewSpell = _resolve_mechanic("hocus_pocus", spells.Spell)
|
||||||
self.assertTrue(issubclass(NewSpell, spells.Spell))
|
self.assertTrue(issubclass(NewSpell, spells.Spell))
|
||||||
|
|
||||||
# Test direct resolution of a proper subclass
|
# Test direct resolution of a proper subclass
|
||||||
class MySpell(spells.Spell):
|
class MySpell(spells.Spell):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
NewSpell = _resolve_mechanic(MySpell, spells, spells.Spell)
|
NewSpell = _resolve_mechanic(MySpell, spells.Spell)
|
||||||
|
|
||||||
def test_wield_weapon(self):
|
def test_wield_weapon(self):
|
||||||
char = Character()
|
char = Character()
|
||||||
|
|||||||
Reference in New Issue
Block a user