adding rarity

This commit is contained in:
evilchili 2023-12-24 12:24:33 -08:00
parent 797c807e58
commit d7f4f2ed2d
4 changed files with 73 additions and 23 deletions

View File

@ -16,7 +16,9 @@ app_state = {}
@app.callback()
def main():
def main(
cr: int = typer.Option(default=None, help='The Challenge Rating to use when determining rarity.'),
):
debug = os.getenv("FANITEM_DEBUG", None)
logging.basicConfig(
format="%(name)s %(message)s",
@ -25,20 +27,21 @@ def main():
)
logging.getLogger('markdown_it').setLevel(logging.ERROR)
app_state['cr'] = cr or 0
app_state['data'] = Path(__file__).parent / Path("sources")
@app.command()
def weapon(count: int = typer.Option(1, help="The number of weapons to generate.")):
console = Console()
for weapon in WeaponGenerator().random(count):
for weapon in WeaponGenerator().random(count=count, challenge_rating=app_state['cr']):
console.print(weapon.details)
@app.command()
def magic_weapon(count: int = typer.Option(1, help="The number of weapons to generate.")):
console = Console()
for weapon in MagicWeaponGenerator().random(count):
for weapon in MagicWeaponGenerator().random(count=count, challenge_rating=app_state['cr']):
console.print(weapon.details)

View File

@ -5,7 +5,6 @@ metadata:
- adjective
frequencies:
default:
magic: 1.0
fire: 1.0
cold: 1.0
acid: 1.0
@ -16,9 +15,6 @@ metadata:
force: 1.0
necrotic: 1.0
radiant: 1.0
magic:
- magic
- magical
fire:
- flames, fire
- flaming, burning

View File

@ -1,15 +1,46 @@
# 5e Iteam Rarity Distributions By Challenge Rating
#
# This distribution is based on this excellent analysis of the DMG loot tables, though
# I have smoothed and tweaked a little bit (the CR17+ frequencies are brokekn IMO):
#
# https://www.enworld.org/threads/analysis-of-typical-magic-item-distribution.395770/
#
metadata:
headers:
- Rarity
- rarity
frequencies:
default:
Common: 1.0
Uncommon: 0.8
Rare: 0.5
Legendary: 0.1
Unique: 0.05
Common:
Uncommon:
Rare:
Legendary:
Unique:
'default':
common: 1.0
uncommon: 1.0
rare: 1.0
very rare: 1.0
legendary: 1.0
'1-4':
common: 0.75
uncommon: 0.5
rare: 0.25
very rare: 0.0
legendary: 0.0
'5-10':
common: 0.5
uncommon: 0.75
rare: 0.25
very rare: 0.05
legendary: 0.0
'11-16':
common: 0.25
uncommon: 0.5
rare: 0.75
very rare: 0.5
legendary: 0.1
'17':
common: 0.05
uncommon: 0.05
rare: 0.5
very rare: 0.5
legendary: 0.3
common:
uncommon:
rare:
very rare:
legendary:

View File

@ -12,7 +12,7 @@ from random_sets.sets import WeightedSet, DataSourceSet
sources = Path(__file__).parent / Path("sources")
MAGIC_DAMAGE = DataSourceSet(sources / Path('magic_damage_types.yaml'))
WEAPON_TYPES = DataSourceSet(sources / Path('weapons.yaml'))
# RARITY = DataSourceSet(sources / Path('rarity.yaml'))
RARITY = DataSourceSet(sources / Path('rarity.yaml'))
@dataclass
@ -143,9 +143,11 @@ class ItemGenerator:
self,
templates: WeightedSet,
types: WeightedSet,
rarity: WeightedSet = RARITY,
):
self.types = types
self.templates = templates
self.rarity = rarity
def random_properties(self) -> dict:
"""
@ -167,14 +169,30 @@ class ItemGenerator:
properties = {
'template': self.templates.random(),
'type': self.types.random(),
'rarity': self.rarity.random(),
}
return properties
def random(self, count: int = 1) -> list:
def random(self, count: int = 1, challenge_rating: int = 0) -> list:
"""
Generate one or more random Item instances by selecting random values
from the available types and template
"""
# select the appropriate frequency distributionnb ased on the specified
# challenge rating. By default, all rarities are weighted equally.
if challenge_rating in range(1, 5):
frequency = '1-4'
elif challenge_rating in range(5, 11):
frequency = '5-10'
elif challenge_rating in range(11, 17):
frequency = '11-16'
elif challenge_rating >= 17:
frequency = '17'
else:
frequency = 'default'
self.rarity.set_frequency(frequency)
items = []
for _ in range(count):
items.append(self.item_class.from_dict(**self.random_properties()))
@ -192,10 +210,11 @@ class WeaponGenerator(ItemGenerator):
self,
templates: WeightedSet = None,
types: WeightedSet = WEAPON_TYPES,
rarity: WeightedSet = RARITY,
):
if not templates:
templates = WeightedSet(('{type.name}', 1.0),)
super().__init__(types=types, templates=templates)
super().__init__(types=types, templates=templates, rarity=rarity)
class MagicWeaponGenerator(WeaponGenerator):
@ -206,6 +225,7 @@ class MagicWeaponGenerator(WeaponGenerator):
self,
templates: WeightedSet = None,
types: WeightedSet = WEAPON_TYPES,
rarity: WeightedSet = RARITY,
magic: WeightedSet = MAGIC_DAMAGE,
):
self.magic = magic
@ -216,7 +236,7 @@ class MagicWeaponGenerator(WeaponGenerator):
# "Burning Lance"
('{magic.adjective} {type.name}', 1.0),
)
super().__init__(types=types, templates=templates)
super().__init__(types=types, templates=templates, rarity=rarity)
def random_properties(self):
"""