|
@@ -4,6 +4,8 @@ import pickle
|
|
|
import pprint
|
|
|
import re
|
|
|
|
|
|
+from copy import deepcopy
|
|
|
+
|
|
|
|
|
|
charsheet = {
|
|
|
'bab': 9,
|
|
@@ -24,6 +26,7 @@ charsheet = {
|
|
|
'improved unarmed strike',
|
|
|
'combat expertise',
|
|
|
'point blank shot',
|
|
|
+ 'point-blank shot',
|
|
|
'deadly aim',
|
|
|
'improved bull rush',
|
|
|
'improved overrun',
|
|
@@ -50,6 +53,26 @@ charsheet = {
|
|
|
'martial focus',
|
|
|
'weapon training class feature',
|
|
|
'combat reflexes',
|
|
|
+ 'you have no levels in a class that has the grit class feature',
|
|
|
+ 'any combat feat',
|
|
|
+ 'any good alignment',
|
|
|
+ 'bravery +1 class feature',
|
|
|
+ 'human',
|
|
|
+ 'medium size',
|
|
|
+ 'no levels in a class that has the favored enemy class feature',
|
|
|
+ 'no levels in a class that has the panache class feature',
|
|
|
+ 'nonlawful',
|
|
|
+ 'proficiency with selected weapon',
|
|
|
+ 'proficient with all martial weapons',
|
|
|
+ 'proficiency with weapon',
|
|
|
+ 'proficiency with chosen weapon',
|
|
|
+ 'proficiency with armor spikes',
|
|
|
+ 'proficient with armor spikes',
|
|
|
+ 'proficient with scimitar',
|
|
|
+ 'proficient with sing',
|
|
|
+ 'susceptibility to bleed damage',
|
|
|
+ 'and proficiency with the selected weapon.',
|
|
|
+ 'bravery class feature',
|
|
|
],
|
|
|
'skill': [
|
|
|
('knowledge (arcane)', 9),
|
|
@@ -83,8 +106,6 @@ with open('feats.pickle', 'rb') as f:
|
|
|
|
|
|
|
|
|
def texify(textstr):
|
|
|
- textstr = re.sub(r'â', '\textemdash', textstr)
|
|
|
- textstr = re.sub(r'"', "''", textstr)
|
|
|
return textstr
|
|
|
|
|
|
|
|
@@ -97,31 +118,34 @@ def fillsreqs(pr, charsheet):
|
|
|
qual = True
|
|
|
for attr in ['str', 'dex', 'con', 'int', 'wis', 'cha', 'bab']:
|
|
|
if attr in pr:
|
|
|
- if int(pr[attr]) > charsheet[attr]:
|
|
|
+ if int(pr[attr][0]) > charsheet[attr]:
|
|
|
qual = False
|
|
|
- if 'level' in pr:
|
|
|
- for l in pr['level']:
|
|
|
- print(l)
|
|
|
- llqual = False
|
|
|
- for ll in charsheet['level']:
|
|
|
- print(ll)
|
|
|
- if l[0] == ll[0] and int(l[1]) <= ll[1]:
|
|
|
- llqual = True
|
|
|
- break
|
|
|
- if llqual == False:
|
|
|
- qual = False
|
|
|
+ if 'level' in pr:
|
|
|
+ for l in pr['level']:
|
|
|
+ llqual = False
|
|
|
+ for ll in charsheet['level']:
|
|
|
+ if l[0] == ll[0] and int(l[1]) <= ll[1]:
|
|
|
+ llqual = True
|
|
|
break
|
|
|
- if 'skill' in pr:
|
|
|
- for s in pr['skill']:
|
|
|
- squal = False
|
|
|
- for cs in charsheet['skill']:
|
|
|
- if s[0] == cs[0] and int(s[1]) <= cs[1]:
|
|
|
- csqual = True
|
|
|
- break
|
|
|
- if csqual == False:
|
|
|
- qual = False
|
|
|
+ if llqual == False:
|
|
|
+ qual = False
|
|
|
+ break
|
|
|
+ if 'skill' in pr:
|
|
|
+ for s in pr['skill']:
|
|
|
+ squal = False
|
|
|
+ for cs in charsheet['skill']:
|
|
|
+ if s[0] == cs[0] and int(s[1]) <= cs[1]:
|
|
|
+ squal = True
|
|
|
break
|
|
|
- return qual
|
|
|
+ if squal == False:
|
|
|
+ qual = False
|
|
|
+ break
|
|
|
+ if 'feat' in pr:
|
|
|
+ for f in pr['feat']:
|
|
|
+ if f != '' and f not in charsheet['feat']:
|
|
|
+ qual = False
|
|
|
+
|
|
|
+ return qual
|
|
|
|
|
|
|
|
|
def qualfeat(feat, charsheet):
|
|
@@ -134,7 +158,19 @@ def qualfeat(feat, charsheet):
|
|
|
|
|
|
|
|
|
def qualfeats(feats, charsheet):
|
|
|
- return [f for f in feats if qualfeat(f, charsheet)]
|
|
|
+ return [f for f in feats if qualfeat(f, charsheet) and f['name'].lower() not in charsheet['feat']]
|
|
|
+
|
|
|
+
|
|
|
+def addchains(feats, charsheet):
|
|
|
+ featnames = [f['name'] for f in feats]
|
|
|
+ for f in feats:
|
|
|
+ newreqs = deepcopy(charsheet)
|
|
|
+ newreqs['feat'].append(f['name'].lower())
|
|
|
+ newcandidates = qualfeats(allfeats, newreqs)
|
|
|
+ newfeats = [ nf for nf in newcandidates if nf['name'] not in featnames ]
|
|
|
+
|
|
|
+ if len(newfeats) > 0:
|
|
|
+ f['chain'] = newfeats
|
|
|
|
|
|
|
|
|
def prefeats(feats):
|
|
@@ -163,6 +199,9 @@ def asfeat(feat):
|
|
|
if feat['special']:
|
|
|
featsnip += '\\textbf{Special:} %s\n\n' % feat['special']
|
|
|
|
|
|
+ if 'chain' in feat:
|
|
|
+ featsnip += chainfeats(feat['chain'])
|
|
|
+
|
|
|
return featsnip
|
|
|
|
|
|
def aschainfeat(feat):
|
|
@@ -176,31 +215,62 @@ def aschainfeat(feat):
|
|
|
|
|
|
|
|
|
def chainfeats(feats):
|
|
|
- chainsnip = '\begin{itemize}\n\n'
|
|
|
+ chainsnip = '\\begin{itemize}\n\n'
|
|
|
for f in feats:
|
|
|
chainsnip += aschainfeat(f)
|
|
|
- chainsnip += '\end{itemize}'
|
|
|
+ chainsnip += '\end{itemize}\n\n'
|
|
|
|
|
|
return chainsnip
|
|
|
|
|
|
-
|
|
|
-if __name__ == '__main__':
|
|
|
- sectsnip = ''
|
|
|
+def takenfeats(cs):
|
|
|
+ taken = []
|
|
|
for f in sorted(charsheet['feat']):
|
|
|
ff = grabfeat(allfeats, f)
|
|
|
if ff:
|
|
|
- sectsnip += asfeat(ff)
|
|
|
- print(sectsnip)
|
|
|
+ taken.append(ff)
|
|
|
+ return taken
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
|
|
|
+ # generate LaTeX for taken feats
|
|
|
sectsnip = ''
|
|
|
+ for f in takenfeats(charsheet):
|
|
|
+ sectsnip += asfeat(f)
|
|
|
+
|
|
|
+ with open('taken.snip', 'w') as f:
|
|
|
+ print(sectsnip, file=f)
|
|
|
+
|
|
|
+ # generate lists of qualifying feats and one-step chains
|
|
|
+
|
|
|
+ cantake = qualfeats(allfeats, charsheet)
|
|
|
+
|
|
|
+ addchains(cantake, charsheet)
|
|
|
+
|
|
|
+ # split list into one-offs, and feats with chaining
|
|
|
+
|
|
|
+ singles = []
|
|
|
+ chainers = []
|
|
|
+ for f in cantake:
|
|
|
+ print(f['name'])
|
|
|
+ if 'chain' in f:
|
|
|
+ chainers.append(f)
|
|
|
+ else:
|
|
|
+ singles.append(f)
|
|
|
+
|
|
|
+ # LaTeXify both lists
|
|
|
+
|
|
|
+ singlesnip = ''
|
|
|
+ for f in singles:
|
|
|
+ singlesnip += asfeat(f)
|
|
|
|
|
|
+ with open('singles.snip', 'w') as f:
|
|
|
+ print(singlesnip, file=f)
|
|
|
|
|
|
-# for f in allfeats:
|
|
|
-# if 'skill' in f['prereqs']:
|
|
|
-# pprint.pprint(f['prereqs']['skill'])
|
|
|
+ chainsnip = ''
|
|
|
+ for f in chainers:
|
|
|
+ chainsnip += asfeat(f)
|
|
|
|
|
|
-# outfeats = sorted(prefeats, key=lambda x: prefeats[x])
|
|
|
+ with open('chainers.snip', 'w') as f:
|
|
|
+ print(chainsnip, file = f)
|
|
|
|
|
|
-# for of in outfeats:
|
|
|
-# print("%s, %s" % (of, prefeats[of]))
|
|
|
|