adding conversion utils for 5e.tools json data

This commit is contained in:
evilchili 2023-12-19 23:52:09 -08:00
parent bc9052242a
commit e073647e5d
6 changed files with 579 additions and 5 deletions

View File

@ -1,15 +1,19 @@
import logging import logging
import os import os
from pathlib import Path
import typer import typer
from rich.logging import RichHandler from rich.logging import RichHandler
from rich.console import Console from rich.console import Console
# from rich.table import Table
from dnd_item.types import Item from dnd_item.types import random_item
from dnd_item import five_e
app = typer.Typer() app = typer.Typer()
app_state = {}
@app.callback() @app.callback()
@ -22,9 +26,20 @@ def main():
) )
logging.getLogger('markdown_it').setLevel(logging.ERROR) logging.getLogger('markdown_it').setLevel(logging.ERROR)
app_state['data'] = Path(__file__).parent / Path("sources")
@app.command() @app.command()
def item(count: int = typer.Option(1, help="The number of items to generate.")): def item(count: int = typer.Option(1, help="The number of items to generate.")):
console = Console(width=80) items = random_item(count)
for _ in range(count): console = Console()
console.print(Item()) for item in items:
console.print(f"{item['Name']} of {item['Enchantment Noun']} "
f"({item['Damage Dice']} {item['Damage Type']} + "
f"{item['Enchantment Damage']} {item['Enchantment Type']})")
@app.command()
def convert():
src = five_e.weapons()
print(src.as_yaml)

90
dnd_item/five_e.py Normal file
View File

@ -0,0 +1,90 @@
import json
import yaml
from collections import defaultdict
from rolltable.tables import DataSource
from pathlib import Path
sources = Path(__file__).parent / Path("sources")
RARITY = {
'unknown': 'common',
'none': 'common',
'': ''
}
TYPE = {
'M': 'martial',
'R': 'ranged',
'': ''
}
DAMAGE = {
'S': 'Slashing',
'P': 'Piercing',
'B': 'Bludgeoning',
'': ''
}
PROPERTIES = {
'F': 'finesse',
'AF': 'firearm',
'A': 'ammmunition',
'T': 'thrown',
'L': 'light',
'2H': 'two-handed',
'V': 'versatile',
'RLD': 'reload',
'LD': 'loading',
'S': 'special',
'H': 'heavy',
'R': 'reach',
}
class Weapons(DataSource):
"""
A rolltables data source backed by a 5e.tools json data file. used to
convert the 5e.tools data to the yaml format consumed by dnd-rolltables.
"""
def read_source(self) -> None:
src = json.load(self.source)['baseitem']
self.data = defaultdict(list)
headers = ['Rarity', 'Name', 'Category', 'Type', 'Weight', 'Damage Type',
'Damage Dice', 'Range', 'Reload', 'Value', 'Properties']
for item in src:
if not item.get('weapon', False):
continue
if item.get('age', False):
continue
rarity = RARITY.get(item['rarity'], 'Common').capitalize()
itype = TYPE.get(item['type'], '_unknown').capitalize()
properties = ', '.join([PROPERTIES[p] for p in item.get('property', [])])
self.data[rarity].append({
item['name'].capitalize(): [
item['weaponCategory'],
itype,
str(item.get('weight', 0)),
DAMAGE.get(item.get('dmgType', '')),
item.get('dmg1', None),
item.get('range', None),
str(item.get('reload', '')),
str(item.get('value', '')),
properties,
]
})
self.metadata = {'headers': headers}
@property
def as_yaml(self) -> str:
return yaml.dump({'metadata': self.metadata}) + yaml.dump(dict(self.data))
def weapons(source_path: str = 'items-base.json') -> dict:
with open(sources / Path(source_path)) as filehandle:
ds = Weapons(source=filehandle)
return ds

View File

@ -0,0 +1,13 @@
metadata:
headers:
- Rarity
- Enchantment Type
- Enchantment Noun
- Enchantment Adjective
Common:
Fire:
- Flames
- Flaming
Ice:
- Ice
- Freezing

435
dnd_item/sources/types.yaml Normal file
View File

@ -0,0 +1,435 @@
metadata:
headers:
- Rarity
- Name
- Category
- Type
- Weight
- Damage Type
- Damage Dice
- Range
- Reload
- Value
- Properties
Common:
- Battleaxe:
- martial
- Martial
- '4'
- Slashing
- 1d8
- null
- ''
- '1000'
- versatile
- Blowgun:
- martial
- Ranged
- '1'
- Piercing
- '1'
- 25/100
- ''
- '1000'
- ammmunition, loading
- Club:
- simple
- Martial
- '2'
- Bludgeoning
- 1d4
- null
- ''
- '10'
- light
- Dagger:
- simple
- Martial
- '1'
- Piercing
- 1d4
- 20/60
- ''
- '200'
- finesse, light, thrown
- Dart:
- simple
- Ranged
- '0.25'
- Piercing
- 1d4
- 20/60
- ''
- '5'
- finesse, thrown
- Double-bladed scimitar:
- martial
- Martial
- '6'
- Slashing
- 2d4
- null
- ''
- '10000'
- special, two-handed
- Flail:
- martial
- Martial
- '2'
- Bludgeoning
- 1d8
- null
- ''
- '1000'
- ''
- Glaive:
- martial
- Martial
- '6'
- Slashing
- 1d10
- null
- ''
- '2000'
- heavy, reach, two-handed
- Greataxe:
- martial
- Martial
- '7'
- Slashing
- 1d12
- null
- ''
- '3000'
- heavy, two-handed
- Greatclub:
- simple
- Martial
- '10'
- Bludgeoning
- 1d8
- null
- ''
- '20'
- two-handed
- Greatsword:
- martial
- Martial
- '6'
- Slashing
- 2d6
- null
- ''
- '5000'
- heavy, two-handed
- Halberd:
- martial
- Martial
- '6'
- Slashing
- 1d10
- null
- ''
- '2000'
- heavy, reach, two-handed
- Hand crossbow:
- martial
- Ranged
- '3'
- Piercing
- 1d6
- 30/120
- ''
- '7500'
- ammmunition, light, loading
- Handaxe:
- simple
- Martial
- '2'
- Slashing
- 1d6
- 20/60
- ''
- '500'
- light, thrown
- Heavy crossbow:
- martial
- Ranged
- '18'
- Piercing
- 1d10
- 100/400
- ''
- '5000'
- ammmunition, heavy, loading, two-handed
- Hooked shortspear:
- martial
- Martial
- '2'
- Piercing
- 1d4
- null
- ''
- ''
- light
- Hoopak:
- martial
- Martial
- '2'
- Piercing
- 1d6
- 40/160
- ''
- '10'
- ammmunition, finesse, special, two-handed
- Javelin:
- simple
- Martial
- '2'
- Piercing
- 1d6
- 30/120
- ''
- '50'
- thrown
- Lance:
- martial
- Martial
- '6'
- Piercing
- 1d12
- null
- ''
- '1000'
- reach, special
- Light crossbow:
- simple
- Ranged
- '5'
- Piercing
- 1d8
- 80/320
- ''
- '2500'
- ammmunition, loading, two-handed
- Light hammer:
- simple
- Martial
- '2'
- Bludgeoning
- 1d4
- 20/60
- ''
- '200'
- light, thrown
- Light repeating crossbow:
- simple
- Ranged
- '5'
- Piercing
- 1d8
- 40/160
- ''
- ''
- ammmunition, two-handed
- Longbow:
- martial
- Ranged
- '2'
- Piercing
- 1d8
- 150/600
- ''
- '5000'
- ammmunition, heavy, two-handed
- Longsword:
- martial
- Martial
- '3'
- Slashing
- 1d8
- null
- ''
- '1500'
- versatile
- Mace:
- simple
- Martial
- '4'
- Bludgeoning
- 1d6
- null
- ''
- '500'
- ''
- Maul:
- martial
- Martial
- '10'
- Bludgeoning
- 2d6
- null
- ''
- '1000'
- heavy, two-handed
- Morningstar:
- martial
- Martial
- '4'
- Piercing
- 1d8
- null
- ''
- '1500'
- ''
- Net:
- martial
- Ranged
- '3'
- ''
- null
- 5/15
- ''
- '100'
- special, thrown
- Pike:
- martial
- Martial
- '18'
- Piercing
- 1d10
- null
- ''
- '500'
- heavy, reach, two-handed
- Quarterstaff:
- simple
- Martial
- '4'
- Bludgeoning
- 1d6
- null
- ''
- '20'
- versatile
- Rapier:
- martial
- Martial
- '2'
- Piercing
- 1d8
- null
- ''
- '2500'
- finesse
- Scimitar:
- martial
- Martial
- '3'
- Slashing
- 1d6
- null
- ''
- '2500'
- finesse, light
- Shortbow:
- simple
- Ranged
- '2'
- Piercing
- 1d6
- 80/320
- ''
- '2500'
- ammmunition, two-handed
- Shortsword:
- martial
- Martial
- '2'
- Piercing
- 1d6
- null
- ''
- '1000'
- finesse, light
- Sickle:
- simple
- Martial
- '2'
- Slashing
- 1d4
- null
- ''
- '100'
- light
- Sling:
- simple
- Ranged
- '0'
- Bludgeoning
- 1d4
- 30/120
- ''
- '10'
- ammmunition
- Spear:
- simple
- Martial
- '3'
- Piercing
- 1d6
- 20/60
- ''
- '100'
- thrown, versatile
- Trident:
- martial
- Martial
- '4'
- Piercing
- 1d6
- 20/60
- ''
- '500'
- thrown, versatile
- War pick:
- martial
- Martial
- '2'
- Piercing
- 1d8
- null
- ''
- '500'
- ''
- Warhammer:
- martial
- Martial
- '2'
- Bludgeoning
- 1d8
- null
- ''
- '1500'
- versatile
- Whip:
- martial
- Martial
- '3'
- Slashing
- 1d4
- null
- ''
- '200'
- finesse, reach
- Yklwa:
- simple
- Martial
- '3'
- Piercing
- 1d8
- 10/30
- ''
- '100'
- thrown

View File

@ -1,2 +1,21 @@
from rolltable import tables
from pathlib import Path
sources = Path(__file__).parent / Path("sources")
class Item: class Item:
pass pass
def random_item(count=1):
types = (sources / Path('types.yaml')).read_text()
enchantments = (sources / Path('enchantments.yaml')).read_text()
items = []
for _ in range(count):
rt = tables.RollTable([types, enchantments], die=1, hide_rolls=True)
item = dict(zip(rt.rows[0], rt.rows[1]))
item['Enchantment Damage'] = '1d4'
items.append(item)
return items

View File

@ -14,6 +14,8 @@ rich = "^13.7.0"
typer = "^0.9.0" typer = "^0.9.0"
dice = "^4.0.0" dice = "^4.0.0"
dnd-rolltable = { git = "https://github.com/evilchili/dnd-rolltable", branch='main' }
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
pytest = "^7.4.3" pytest = "^7.4.3"
black = "^23.3.0" black = "^23.3.0"