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

View File

@ -5,7 +5,6 @@ metadata:
- adjective - adjective
frequencies: frequencies:
default: default:
magic: 1.0
fire: 1.0 fire: 1.0
cold: 1.0 cold: 1.0
acid: 1.0 acid: 1.0
@ -16,9 +15,6 @@ metadata:
force: 1.0 force: 1.0
necrotic: 1.0 necrotic: 1.0
radiant: 1.0 radiant: 1.0
magic:
- magic
- magical
fire: fire:
- flames, fire - flames, fire
- flaming, burning - 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: metadata:
headers: headers:
- Rarity - rarity
frequencies: frequencies:
default: 'default':
Common: 1.0 common: 1.0
Uncommon: 0.8 uncommon: 1.0
Rare: 0.5 rare: 1.0
Legendary: 0.1 very rare: 1.0
Unique: 0.05 legendary: 1.0
Common: '1-4':
Uncommon: common: 0.75
Rare: uncommon: 0.5
Legendary: rare: 0.25
Unique: 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") sources = Path(__file__).parent / Path("sources")
MAGIC_DAMAGE = DataSourceSet(sources / Path('magic_damage_types.yaml')) MAGIC_DAMAGE = DataSourceSet(sources / Path('magic_damage_types.yaml'))
WEAPON_TYPES = DataSourceSet(sources / Path('weapons.yaml')) WEAPON_TYPES = DataSourceSet(sources / Path('weapons.yaml'))
# RARITY = DataSourceSet(sources / Path('rarity.yaml')) RARITY = DataSourceSet(sources / Path('rarity.yaml'))
@dataclass @dataclass
@ -143,9 +143,11 @@ class ItemGenerator:
self, self,
templates: WeightedSet, templates: WeightedSet,
types: WeightedSet, types: WeightedSet,
rarity: WeightedSet = RARITY,
): ):
self.types = types self.types = types
self.templates = templates self.templates = templates
self.rarity = rarity
def random_properties(self) -> dict: def random_properties(self) -> dict:
""" """
@ -167,14 +169,30 @@ class ItemGenerator:
properties = { properties = {
'template': self.templates.random(), 'template': self.templates.random(),
'type': self.types.random(), 'type': self.types.random(),
'rarity': self.rarity.random(),
} }
return properties 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 Generate one or more random Item instances by selecting random values
from the available types and template 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 = [] items = []
for _ in range(count): for _ in range(count):
items.append(self.item_class.from_dict(**self.random_properties())) items.append(self.item_class.from_dict(**self.random_properties()))
@ -192,10 +210,11 @@ class WeaponGenerator(ItemGenerator):
self, self,
templates: WeightedSet = None, templates: WeightedSet = None,
types: WeightedSet = WEAPON_TYPES, types: WeightedSet = WEAPON_TYPES,
rarity: WeightedSet = RARITY,
): ):
if not templates: if not templates:
templates = WeightedSet(('{type.name}', 1.0),) templates = WeightedSet(('{type.name}', 1.0),)
super().__init__(types=types, templates=templates) super().__init__(types=types, templates=templates, rarity=rarity)
class MagicWeaponGenerator(WeaponGenerator): class MagicWeaponGenerator(WeaponGenerator):
@ -206,6 +225,7 @@ class MagicWeaponGenerator(WeaponGenerator):
self, self,
templates: WeightedSet = None, templates: WeightedSet = None,
types: WeightedSet = WEAPON_TYPES, types: WeightedSet = WEAPON_TYPES,
rarity: WeightedSet = RARITY,
magic: WeightedSet = MAGIC_DAMAGE, magic: WeightedSet = MAGIC_DAMAGE,
): ):
self.magic = magic self.magic = magic
@ -216,7 +236,7 @@ class MagicWeaponGenerator(WeaponGenerator):
# "Burning Lance" # "Burning Lance"
('{magic.adjective} {type.name}', 1.0), ('{magic.adjective} {type.name}', 1.0),
) )
super().__init__(types=types, templates=templates) super().__init__(types=types, templates=templates, rarity=rarity)
def random_properties(self): def random_properties(self):
""" """