mirror of
https://github.com/Threnklyn/dungeon-sheets.git
synced 2026-05-18 20:23:27 +02:00
113 lines
2.4 KiB
Python
113 lines
2.4 KiB
Python
"""A collection of monsters. Also useful for building a list of wild
|
|
shape forms.
|
|
|
|
"""
|
|
|
|
from abc import ABCMeta
|
|
|
|
|
|
from dungeonsheets.content import Creature
|
|
from dungeonsheets.spells import Spell
|
|
|
|
|
|
xp_by_challenge_rating = {
|
|
0: 10,
|
|
(1 / 8): 25,
|
|
(1 / 4): 50,
|
|
(1 / 2): 100,
|
|
1: 200,
|
|
2: 450,
|
|
3: 700,
|
|
4: 1100,
|
|
5: 1800,
|
|
6: 2300,
|
|
7: 2900,
|
|
8: 3900,
|
|
9: 5000,
|
|
10: 5900,
|
|
11: 7200,
|
|
12: 8400,
|
|
13: 10000,
|
|
14: 11500,
|
|
15: 13000,
|
|
16: 15000,
|
|
17: 18000,
|
|
18: 20000,
|
|
19: 22000,
|
|
20: 25000,
|
|
21: 33000,
|
|
22: 41000,
|
|
23: 50000,
|
|
24: 62000,
|
|
25: 75000,
|
|
26: 90000,
|
|
27: 105000,
|
|
28: 120000,
|
|
29: 130000,
|
|
30: 155000,
|
|
}
|
|
|
|
|
|
def challenge_rating_to_xp(cr):
|
|
"""Determine the XP awarded for slaying a monster with the given
|
|
challenge rating *cr*.
|
|
|
|
"""
|
|
xp = xp_by_challenge_rating[cr]
|
|
return "{:,}".format(xp)
|
|
|
|
|
|
class SpellFactory(ABCMeta):
|
|
"""Meta class to resolve spell strings into the ``spells.Spell``.
|
|
|
|
For classes using this metaclass, the *spell* attribute, if
|
|
present, should be a list of spells that the entity knows. For
|
|
each entry on that list, anything that is not already a spell
|
|
class (so probably a string) will be resolved into the
|
|
corresponding ``spells.Spell`` class.
|
|
|
|
"""
|
|
def __init__(self, name, bases, attrs):
|
|
for idx, spell in enumerate(self.spells):
|
|
TheSpell = self._resolve_mechanic(spell, SuperClass=Spell)
|
|
self.spells[idx] = TheSpell
|
|
|
|
|
|
class Monster(Creature, metaclass=SpellFactory):
|
|
|
|
"""A monster that may be encountered when adventuring."""
|
|
|
|
name = "Generic Monster"
|
|
description = ""
|
|
challenge_rating = 0
|
|
skills = "Perception +3, Stealth +4"
|
|
damage_resistances = ""
|
|
damage_immunities = ""
|
|
damage_vulnerabilities = ""
|
|
condition_immunities = ""
|
|
saving_throws = ""
|
|
# TODO: Consider refactoring stats.Speed to consider all of these
|
|
# just like we do stats.Ability
|
|
swim_speed = 0
|
|
fly_speed = 0
|
|
climb_speed = 0
|
|
burrow_speed = 0
|
|
hp_max = 10
|
|
hit_dice = "1d6"
|
|
spells = []
|
|
|
|
def __init__(self):
|
|
super(Monster, self).__init__()
|
|
|
|
@property
|
|
def is_beast(self):
|
|
is_beast = "beast" in self.description.lower()
|
|
return is_beast
|
|
|
|
def has_feature(self, *args, **kwargs):
|
|
return False
|
|
|
|
@property
|
|
def is_spellcaster(self):
|
|
return len(self.spells) > 0
|