tuning naming algorithm
This commit is contained in:
parent
86c2fce87d
commit
51ecf83357
|
@ -61,7 +61,7 @@ def table(
|
||||||
True,
|
True,
|
||||||
help='If True, collapse multiple die values with the same option.'),
|
help='If True, collapse multiple die values with the same option.'),
|
||||||
width: int = typer.Option(
|
width: int = typer.Option(
|
||||||
120,
|
180,
|
||||||
help='Width of the table.'),
|
help='Width of the table.'),
|
||||||
output: OUTPUT_FORMATS = typer.Option(
|
output: OUTPUT_FORMATS = typer.Option(
|
||||||
'text',
|
'text',
|
||||||
|
|
|
@ -3,22 +3,24 @@ metadata:
|
||||||
- name
|
- name
|
||||||
- description
|
- description
|
||||||
light:
|
light:
|
||||||
- 'A light weapon is small and easy to handle, making it ideal for use when fighting with two weapons.'
|
- "A light weapon is small and easy to handle, making it ideal for use when fighting with two weapons."
|
||||||
thrown:
|
thrown:
|
||||||
- ''
|
- "If a weapon has the thrown property, you can throw the weapon to make a ranged attack. If the weapon is a melee weapon, you use the same ability modifier for that attack roll and damage roll that you would use for a melee attack with the weapon."
|
||||||
heavy:
|
heavy:
|
||||||
- ''
|
- "Small creatures have disadvantage on attack rolls with heavy weapons. A heavy weapon’s size and bulk make it too large for a Small creature to use effectively."
|
||||||
special:
|
|
||||||
- ''
|
|
||||||
two-handed:
|
two-handed:
|
||||||
- ''
|
- "This weapon requires two hands when you attack with it."
|
||||||
versatile:
|
versatile:
|
||||||
- ''
|
- "This weapon can be used with one or two hands. A damage value in parentheses appears with the property—the damage when the weapon is used with two hands to make a melee attack."
|
||||||
finesse:
|
finesse:
|
||||||
- ''
|
- "When making an attack with a finesse weapon, you use your choice of your Strength or Dexterity modifier for the attack and damage rolls. You must use the same modifier for both rolls."
|
||||||
ammunition:
|
ammunition:
|
||||||
- ''
|
- "You can use a weapon that has the ammunition property to make a ranged attack only if you have ammunition to fire from the weapon. Each time you attack with the weapon, you expend one piece of ammunition. Drawing the ammunition from a quiver, case, or other container is part of the attack (you need a free hand to load a one-handed weapon)."
|
||||||
reach:
|
reach:
|
||||||
- ''
|
- "This weapon adds 5 feet to your reach when you attack with it, as well as when determining your reach for opportunity attacks with it."
|
||||||
loading:
|
loading:
|
||||||
- ''
|
- "Because of the time required to load this weapon, you can fire only one piece of ammunition from it when you use an action, bonus action, or reaction to fire it, regardless of the number of attacks you can normally make."
|
||||||
|
ranged:
|
||||||
|
- "A weapon that can be used to make a ranged attack has a range in parentheses after the ammunition or thrown property. The range lists two numbers. The first is the weapon’s normal range in feet, and the second indicates the weapon’s long range. When attacking a target beyond normal range, you have disadvantage on the attack roll. You can’t attack a target beyond the weapon’s long range."
|
||||||
|
special:
|
||||||
|
- "Refer to Player's Handbook."
|
||||||
|
|
|
@ -17,7 +17,7 @@ enchanted:
|
||||||
- 0
|
- 0
|
||||||
- weapon
|
- weapon
|
||||||
magical:
|
magical:
|
||||||
- 'striking, smacking'
|
- 'legend, legendary strking, legendary smacking, legendary strikes'
|
||||||
- '+3'
|
- '+3'
|
||||||
- This magical weapon grants +3 to attack and damage rolls.
|
- This magical weapon grants +3 to attack and damage rolls.
|
||||||
- '{damage_type}'
|
- '{damage_type}'
|
||||||
|
|
|
@ -17,7 +17,7 @@ enchanted:
|
||||||
- 0
|
- 0
|
||||||
- weapon
|
- weapon
|
||||||
magical:
|
magical:
|
||||||
- 'striking, smacking'
|
- 'precision, precise striking, precise smacking, precise strikes'
|
||||||
- '+2'
|
- '+2'
|
||||||
- This magical weapon grants +2 to attack and damage rolls.
|
- This magical weapon grants +2 to attack and damage rolls.
|
||||||
- '{damage_type}'
|
- '{damage_type}'
|
||||||
|
|
|
@ -32,7 +32,7 @@ enchanted:
|
||||||
- null
|
- null
|
||||||
- weapon
|
- weapon
|
||||||
magical:
|
magical:
|
||||||
- 'striking, smacking'
|
- 'honed striking, honed smacking, honed strikes'
|
||||||
- '+1'
|
- '+1'
|
||||||
- This magical weapon grants +1 to attack and damage rolls.
|
- This magical weapon grants +1 to attack and damage rolls.
|
||||||
- '{damage_type}'
|
- '{damage_type}'
|
||||||
|
|
|
@ -17,7 +17,7 @@ enchanted:
|
||||||
- 0
|
- 0
|
||||||
- weapon
|
- weapon
|
||||||
magical:
|
magical:
|
||||||
- 'striking, smacking'
|
- 'might, mighty strking, mighty smacking, mighty strikes'
|
||||||
- '+3'
|
- '+3'
|
||||||
- This magical weapon grants +3 to attack and damage rolls.
|
- This magical weapon grants +3 to attack and damage rolls.
|
||||||
- '{damage_type}'
|
- '{damage_type}'
|
||||||
|
|
|
@ -252,8 +252,11 @@ class GeneratorSource:
|
||||||
(
|
(
|
||||||
item.rarity['sort_order'],
|
item.rarity['sort_order'],
|
||||||
[
|
[
|
||||||
item.name, item.rarity['rarity'],
|
item.name,
|
||||||
item.summary, ', '.join(item.get('properties', []))
|
item.rarity['rarity'],
|
||||||
|
item.summary,
|
||||||
|
', '.join(item.get('properties', [])),
|
||||||
|
item.id
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
for item in self.generator.random(count=count, challenge_rating=self.cr)
|
for item in self.generator.random(count=count, challenge_rating=self.cr)
|
||||||
|
@ -286,6 +289,7 @@ class RollTable(rolltable.types.RollTable):
|
||||||
'Name',
|
'Name',
|
||||||
'Rarity',
|
'Rarity',
|
||||||
'Summary',
|
'Summary',
|
||||||
'Properties'
|
'Properties',
|
||||||
|
'ID',
|
||||||
]
|
]
|
||||||
self._header_excludes = []
|
self._header_excludes = []
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import random
|
import random
|
||||||
|
import base64
|
||||||
|
import hashlib
|
||||||
|
|
||||||
from functools import cached_property
|
from functools import cached_property
|
||||||
|
|
||||||
|
@ -27,14 +29,14 @@ class Weapon(types.Item):
|
||||||
nouns[prop_name] = equal_weights(prop.nouns.split(','), blank=False)
|
nouns[prop_name] = equal_weights(prop.nouns.split(','), blank=False)
|
||||||
if hasattr(prop, 'adjectives'):
|
if hasattr(prop, 'adjectives'):
|
||||||
adjectives[prop_name] = equal_weights(prop.adjectives.split(','), blank=False)
|
adjectives[prop_name] = equal_weights(prop.adjectives.split(','), blank=False)
|
||||||
return (nouns, adjectives)
|
return (nouns, adjectives)
|
||||||
|
|
||||||
def _name_template(self, with_adjectives: bool, with_nouns: bool) -> str:
|
def _name_template(self, with_adjectives: bool, with_nouns: bool) -> str:
|
||||||
num_properties = len(self.properties)
|
num_properties = len(self.properties)
|
||||||
options = []
|
options = []
|
||||||
if with_nouns:
|
if with_nouns and not with_adjectives:
|
||||||
options.append(('{name} of {nouns}', 0.5))
|
options.append(('{name} of {nouns}', 0.5))
|
||||||
if with_adjectives:
|
if with_adjectives and not with_nouns:
|
||||||
options.append(('{adjectives} {name}', 0.5))
|
options.append(('{adjectives} {name}', 0.5))
|
||||||
if with_nouns and with_adjectives:
|
if with_nouns and with_adjectives:
|
||||||
if num_properties == 1:
|
if num_properties == 1:
|
||||||
|
@ -60,22 +62,34 @@ class Weapon(types.Item):
|
||||||
def add_word(key, obj, source):
|
def add_word(key, obj, source):
|
||||||
obj.append(source[key].random().strip())
|
obj.append(source[key].random().strip())
|
||||||
|
|
||||||
|
seen_nouns = dict()
|
||||||
for prop_name in set(list(nouns.keys()) + list(adjectives.keys())):
|
for prop_name in set(list(nouns.keys()) + list(adjectives.keys())):
|
||||||
if prop_name in nouns and prop_name in adjectives:
|
|
||||||
val = random.random()
|
if prop_name in nouns and prop_name not in adjectives:
|
||||||
if val <= 0.4:
|
if prop_name not in seen_nouns:
|
||||||
add_word(prop_name, random_nouns, nouns)
|
add_word(prop_name, random_nouns, nouns)
|
||||||
|
seen_nouns[prop_name] = True
|
||||||
|
|
||||||
|
elif prop_name in adjectives and prop_name not in nouns:
|
||||||
|
add_word(prop_name, random_adjectives, adjectives)
|
||||||
|
|
||||||
|
if prop_name in nouns and prop_name in adjectives:
|
||||||
|
# if the property has both nouns and adjectives, select one
|
||||||
|
# or the other or both, for the weapon name. Both leads to
|
||||||
|
# spurious names like 'thundering dagger of thunder', so we
|
||||||
|
# we reduce the likelihood of this eventuality so it is an
|
||||||
|
# occasionl bit of silliness, not consistently silly.
|
||||||
|
val = random.random()
|
||||||
|
if val <= 0.4 and prop_name not in seen_nouns:
|
||||||
|
add_word(prop_name, random_nouns, nouns)
|
||||||
|
seen_nouns[prop_name] = True
|
||||||
elif val <= 0.8:
|
elif val <= 0.8:
|
||||||
add_word(prop_name, random_adjectives, adjectives)
|
add_word(prop_name, random_adjectives, adjectives)
|
||||||
else:
|
else:
|
||||||
add_word(prop_name, random_nouns, nouns)
|
add_word(prop_name, random_nouns, nouns)
|
||||||
add_word(prop_name, random_adjectives, adjectives)
|
add_word(prop_name, random_adjectives, adjectives)
|
||||||
elif prop_name in nouns:
|
|
||||||
add_word(prop_name, random_nouns, nouns)
|
|
||||||
elif prop_name in adjectives:
|
|
||||||
add_word(prop_name, random_adjectives, adjectives)
|
|
||||||
|
|
||||||
random_nouns = ' '.join(random_nouns)
|
random_nouns = ' and '.join(random_nouns)
|
||||||
random_adjectives = ' '.join(random_adjectives)
|
random_adjectives = ' '.join(random_adjectives)
|
||||||
return (random_nouns, random_adjectives)
|
return (random_nouns, random_adjectives)
|
||||||
|
|
||||||
|
@ -131,7 +145,7 @@ class Weapon(types.Item):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def summary(self):
|
def summary(self):
|
||||||
return f"{self.to_hit} to hit, {self.range} ft., {self.targets} targets. {self.damage_dice}"
|
return f"{self.to_hit} to hit, {self.range} ft., {self.targets} tgts. {self.damage_dice}"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def details(self):
|
def details(self):
|
||||||
|
@ -146,6 +160,13 @@ class Weapon(types.Item):
|
||||||
f"\n{self.description}\n"
|
f"\n{self.description}\n"
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@property
|
||||||
|
def id(self):
|
||||||
|
sha1bytes = hashlib.sha1(''.join([
|
||||||
|
self._name, self.to_hit, self.damage_dice,
|
||||||
|
]).encode())
|
||||||
|
return base64.urlsafe_b64encode(sha1bytes.digest()).decode('ascii')[:10]
|
||||||
|
|
||||||
|
|
||||||
class WeaponGenerator(types.ItemGenerator):
|
class WeaponGenerator(types.ItemGenerator):
|
||||||
item_class = Weapon
|
item_class = Weapon
|
||||||
|
|
Loading…
Reference in New Issue
Block a user