Browse Source

complete, and also still completely buggy.

jmelesky 7 năm trước cách đây
mục cha
commit
f4370ca213
3 tập tin đã thay đổi với 129 bổ sung48 xóa
  1. BIN
      feats.pickle
  2. 108 38
      queryfeats.py
  3. 21 10
      scrapefeats.py

BIN
feats.pickle


+ 108 - 38
queryfeats.py

@@ -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]))
 

+ 21 - 10
scrapefeats.py

@@ -23,8 +23,11 @@ def scrape_featlist(url):
 def sanitext(text):
     rettext = re.sub(r'^:\s+', '', text)
     rettext = re.sub(r'\.$', '', rettext)
+    rettext = re.sub(r'\r', '', rettext)
     rettext = re.sub(r'â\x80\x93', '-', rettext)
     rettext = re.sub(r'â\x80\x99', "'", rettext)
+    rettext = re.sub(r'—', '\textemdash', rettext)
+    rettext = re.sub(r'"', "''", rettext)
     rettext = re.sub(r'ACG', '', rettext)
     rettext = re.sub(r'APG', '', rettext)
     rettext = re.sub(r'ARG', '', rettext)
@@ -56,27 +59,35 @@ def parse_prereqs(reqtext, sep=r'[,;]'):
         elif req.find(' and ') > -1:
             reqs = addreq(reqs, 'and', parse_prereqs(req, sep=r'\Wand\W'))
         else:
-            m = re.search(r'^(\w{3}) (\d{2})$', req)
+            m = re.search(r'^(\w{3}) (\d{1,2})\.?$', req)
             if m:
                 reqs = addreq(reqs, m.group(1), m.group(2))
             else:
-                m = re.search(r'^base\s+attack\s+bonus\s+\+{0,1}(\d+)$', req)
+                m = re.search(r'^dexterity (\d+)', req)
                 if m:
-                    reqs = addreq(reqs, 'bab', m.group(1))
+                    reqs = addreq(reqs, 'dex', m.group(1))
                 else:
-                    m = re.search(r'^(.*?)\Wlevel (\d+)', req)
+                    m = re.search(r'^strength (\d+)', req)
                     if m:
-                        reqs = addreq(reqs, 'level', (m.group(1), m.group(2)))
+                        reqs = addreq(reqs, 'str', m.group(1))
                     else:
-                        m = re.search(r'^(\d+).*level (.*)$', req)
+                        m = re.search(r'^base\W+attack\W+bonus\W+\+{0,1}(\d+)', req)
                         if m:
-                            reqs = addreq(reqs, 'level', (m.group(2), m.group(1)))
+                            reqs = addreq(reqs, 'bab', m.group(1))
                         else:
-                            m = re.search(r'^(.*?) (\d+) rank', req)
+                            m = re.search(r'^(.*?)\Wlevel (\d+)', req)
                             if m:
-                                reqs = addreq(reqs, 'skill', (m.group(1), m.group(2)))
+                                reqs = addreq(reqs, 'level', (m.group(1), m.group(2)))
                             else:
-                                reqs = addreq(reqs, 'feat', req)
+                                m = re.search(r'^(\d+).*level (.*)$', req)
+                                if m:
+                                    reqs = addreq(reqs, 'level', (m.group(2), m.group(1)))
+                                else:
+                                    m = re.search(r'^(.*?) (\d+) rank', req)
+                                    if m:
+                                        reqs = addreq(reqs, 'skill', (m.group(1), m.group(2)))
+                                    else:
+                                        reqs = addreq(reqs, 'feat', req)
 
 
     return reqs