diff options
| author | Your Name <you@example.com> | 2021-04-15 15:23:23 -0400 | 
|---|---|---|
| committer | Your Name <you@example.com> | 2021-04-15 15:23:23 -0400 | 
| commit | dfce4d0398a8bafbb7ad7a31345af181c0269c09 (patch) | |
| tree | 695162ff8cc25e146f52d9e26fe19ffa9934b3d6 /parser/scrapeToJson.py | |
| parent | 9034c3d2533177f7cb7a7ce939ec53f7fa63f60e (diff) | |
| download | dmtool-dfce4d0398a8bafbb7ad7a31345af181c0269c09.tar.gz dmtool-dfce4d0398a8bafbb7ad7a31345af181c0269c09.tar.bz2 dmtool-dfce4d0398a8bafbb7ad7a31345af181c0269c09.zip | |
Added spells
Diffstat (limited to 'parser/scrapeToJson.py')
| -rwxr-xr-x | parser/scrapeToJson.py | 70 | 
1 files changed, 64 insertions, 6 deletions
| diff --git a/parser/scrapeToJson.py b/parser/scrapeToJson.py index d9444c7..24980a1 100755 --- a/parser/scrapeToJson.py +++ b/parser/scrapeToJson.py @@ -4,7 +4,7 @@ import json  import re  import utils -def processMonster(data, weapons, armors): +def processMonster(data, weapons, armors, spells):      names2names = {'ac': 'Armor Class', 'hp': 'Hit Points', 'speed': 'Speed', 'saves': 'Saving Throws', 'd_resistances': 'Damage Resistances?', 'd_vulnerabilities': 'Damage Vulnerabilities', 'd_immunities': 'Damage Immunities', 'c_immunities': 'Condition Immunities', 'senses': 'Senses', 'langs': 'Languages', 'skills': 'Skills'}      desc = {}      for name in names2names: @@ -74,7 +74,8 @@ def processMonster(data, weapons, armors):                      found = True                      bonus = armorDict['ac']                      typ = armorDict['type'] -                    desc['inventory'].append(armorDict) +                    #desc['inventory'].append(armorDict) +                    desc['inventory'].append({'name': a, 'type': 'armor', 'text': '{} armor'.format(a)})                      break              if not found:                  print('Cound not identify armor: {}'.format(a)) @@ -188,8 +189,6 @@ def processMonster(data, weapons, armors):                      if isOr and toAppend['dmg_type'] == details['damage'][-1]['dmg_type'] and toAppend['dmg_die_sides'] == details['damage'][-1]['dmg_die_sides'] + 2:                          details['properties'].append('versatile')                      else: -                        if isOr: -                            print('We got here for {}!!!!!!!!!!!!!!'.format(desc['name']))                          details['damage'].append(toAppend)              details['text'] = re.search('(?s)(_Hit:_ (?:\d+ [^\.]*\.)?)(.*)', action['text']).group(2).strip()              if len(details['damage']) == 0: @@ -198,7 +197,66 @@ def processMonster(data, weapons, armors):              for name, value in utils.formatWeapon(action['name'], details['range'][0], details['range'][1], details['reach'], details['damage'][0]['dmg_type'], details['damage'][0]['dmg_die_count'], details['damage'][0]['dmg_die_sides'], action['text']).items():                  action['attack'][name] = value              if action['attack']['type'] != 'unknown': -                desc['inventory'].append(action['attack']) +                #desc['inventory'].append(action['attack']) +                desc['inventory'].append({'name': action['attack']['name'], 'type': 'weapon', 'text': action['text']}) +        elif 'spellcasting' in action['name']: +            action['type'] = 'spellcasting' +            print('{} has spellcasting!'.format(desc['name'])) +            abilities = ['Intelligence', 'Wisdom', 'Charisma'] +            for ability in abilities: +                if ability in action['text']: +                    if 'spellcasting_ability' in action: +                        print('Uh oh, both {} and {} present!'.format(action['spellcasting_ability'], ability)) +                        exit(1) +                    action['spellcasting_ability'] = ability.lower()[:3] +            if 'spellcasting_ability' not in action: +                print('Uh oh, no spellcasting ability!') +                exit(1) +            # Interpretation of slots differs if is innate or not +            action['innate'] = 'innate' in action['text'] +            # Now, break down by level +            action['levels'] = [] +            def getSpells(text): +                names = [] +                [names.extend(m.split(', ')) for m in re.findall('(?<=\*\*_).*?(?=_\*\*)', text)] +                #ret = [] +                for name in names: +                    found = False +                    for spell in spells: +                        if spell['name'] == name: +                            #ret.append(spell) +                            found = True +                            break +                    if not found: +                        print('Could not find spell: {}!!!!!!!!!!!!'.format(name)) +                #return ret +                return names +            # Sometimes it is in the name (as is case with mephits) +            if '/day' in action['name']: +                slots = int(re.search('(?<=\()\d+', action['name']).group(0)) +                spellNames = getSpells(action['text']) +                action['levels'].append({'slots': slots, 'spells': spellNames}) +            else: +                # Repair pit fiend +                m = re.match('(?sm)^(.+) \d+/day each: ', action['text']) +                if m: +                    action['text'] = re.sub(re.escape(m.group(0)), m.group(0) + '**_', action['text']) +                    action['text'] = re.sub(re.escape(m.group(1)), m.group(1) + '_**\n', action['text']) +                for line in action['text'].split('\n')[1:]: +                    line = line.lower() +                    if all(string not in line for string in ['(', '/day', 'at will']): +                        continue +                    #print('Searching line {}'.format(line)) +                    # If it's "at will", then slots = 0 +                    if 'at will' in line: +                        slots = 0 +                    else: +                        slots = int(re.search('(\d+)( slot|/day)', line).group(1)) +                    spellNames = getSpells(line) +                    action['levels'].append({'slots': slots, 'spells': spellNames}) + +            action['name'] = 'spellcasting' +      # Remove weapon actions from features (they were just added to inventory)      desc['features'] = [a for a in desc['features'] if 'attack' not in a or a['attack']['type'] == 'unknown']      # Get rid of precalculated passive perception @@ -233,4 +291,4 @@ for monster in Path('../../5thSRD/docs/gamemaster_rules/monsters/').glob('*.md')          data = f.read()      Path('monsters/').mkdir(exist_ok=True)      with open('monsters/' + monster.stem + '.json', 'w') as f: -        json.dump(processMonster(data, weapons, armors), f, indent=2) +        json.dump(processMonster(data, weapons, armors, spells), f, indent=2) | 
