Advertisement
Guest User

Untitled

a guest
Oct 13th, 2015
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.84 KB | None | 0 0
  1. import re, json
  2. '''Turns spell blocks into json for use with the 5e shaped spell importer on roll20'''
  3. def parse_spell_plain(spell_file):
  4. '''for spells in plain text, can have markdown formating in description'''
  5. f = open(spell_file)
  6. raw = f.read()
  7. f.close()
  8.  
  9. # print raw
  10. spell = {}
  11.  
  12. # get title
  13. name = re.search(r'(.*)', raw).groups()
  14. print name
  15. spell['name'] = name[0].strip()
  16.  
  17. # get spell level
  18. spell_level = re.search(r'(?=(?:(.*?)-[Ll]evel (\w*)\s*(\(.*\))?|(.*?)\s(?:[Cc]antrip)))',raw).groups()
  19.  
  20. print spell_level
  21. spell['level'] = int(spell_level[0][0]) if spell_level[0] else 0
  22. spell['school'] = (spell_level[1] or spell_level[3]).capitalize().strip()
  23. if spell_level[2]: spell['ritual'] = True
  24.  
  25. # get casting time
  26. time = re.search(r'[Cc]asting [Tt]ime:\s*(.*)',raw).groups()[0].strip()
  27. if '1 action' in time:
  28. spell['castingTime'] = 'action'
  29. elif '1 bonus action' in time:
  30. spell['castingTime'] = 'bonus'
  31. elif '1 minute' in time:
  32. spell['castingTime'] = 'minute'
  33. elif '1 reaction' in time:
  34. spell['castingTime'] = 'reaction'
  35. else:
  36. spell['castingTime'] = time
  37.  
  38. # get range
  39. spell_range = re.search(r'[Rr]ange:\s*(.*)', raw).groups()
  40. if spell_range[0]: spell['range'] = spell_range[0].strip()
  41.  
  42. # get components
  43. m = re.search(r'Components:\s*([Vv])?,?\s*([Ss])?,?\s*([Mm])?(?:\s*\((.*)\))?', raw)
  44. if m:
  45. components = m.groups()
  46. c = {}
  47. if components[0]: c['verbal'] = True
  48. if components[1]: c['somatic'] = True
  49. if components[2]: c['material'] = True
  50. if components[3]: c['materialMaterial'] = components[3]
  51. spell['components'] = c
  52.  
  53. # get duration
  54. duration = re.search(r'[Dd]uration:\s*([Cc]oncentration)?,?\s*(.*)',raw).groups()
  55. # print duration
  56. spell['duration'] = duration[1].strip()
  57. if duration[0]: spell['concentration'] = True
  58.  
  59. # get description and higher levels
  60. desc_all = re.search(r'[Dd]uration.*?$(.*)',raw,re.DOTALL | re.MULTILINE).groups()
  61. desc = re.split(r'[Aa]t [Hh]igher [Ll]evels\.?', desc_all[0])
  62. if spell['castingTime'] is 'reaction':
  63. spell['description'] = time +'\n' + desc[0].strip()
  64. else:
  65. spell['description'] = desc[0].strip()
  66. if len(desc)>1: spell['higherLevel'] = desc[1].strip()
  67.  
  68. # get save
  69. m = re.search(r'\s(\w*)\s*[Ss]aving [Tt]hrow', spell['description'])
  70. save = m.groups() if m else []
  71. # get attack
  72. attack = re.search(r'spell attack',spell['description'])
  73. # get heal
  74. heal = re.search(r'regain.*hit\s*points\s*equal\s*to\s*(\d+d\d+)',spell['description'])
  75.  
  76. # get damage based on two common damage formats
  77. damage = re.findall(r'(\d+d\d+)\s*([\w ]*?)\s*[Dd]amage', spell['description'])
  78. damage_abil = re.search(r'\s(\w*)\s*[Dd]amage equal to (\d+d\d+)', spell['description'])
  79.  
  80. # higher level
  81. hd = None
  82. if 'higherLevel' in spell:
  83. hd = re.search(r'(\d+)(d\d+)', spell['higherLevel'])
  84. hl = re.search(r'\s(\w*)\s*slot level',spell['higherLevel'])
  85. if hd: higher_damage = hd.groups()
  86. if hl: higher_levels = hl.groups()
  87.  
  88. # print damage
  89. spell_stats = {}
  90. if save and save[0]:
  91. spell_stats['ability'] = save[0]
  92. suc = re.search(r'successful save.*(half as much damage)',spell['description'])
  93. if suc: spell_stats['saveSuccess'] = 'half damage'
  94. if save or attack or heal:
  95. if damage:
  96. spell_stats['damage'] = damage[0][0]
  97. spell_stats['damageType'] = damage[0][1]
  98. if len(damage) > 1:
  99. spell_stats['secondaryDamage'] = damage[1][0]
  100. spell_stats['secondaryDamageType'] = damage[1][1]
  101. elif damage_abil:
  102. d = damage_abil.groups()
  103. spell_stats['damage'] = d[1]
  104. spell_stats['damageType'] = d[0]
  105. spell_stats['castingStat'] = True
  106. elif heal:
  107. h = heal.groups()
  108. spell_stats['amount'] = h[0]
  109. spell_stats['castingStat'] = True
  110. if hd:
  111. spell_stats['higherLevelDice'] = .49 if higher_levels and 'two' in higher_levels else higher_damage[0]
  112. spell_stats['higherLevelDie'] = higher_damage[1]
  113. if 'secondaryDamage' in spell_stats:
  114. spell_stats['higherLevelSecondaryDice'] = spell_stats['higherLevelDice']
  115. spell_stats['higherLevelSecondaryDie'] = spell_stats['higherLevelDie']
  116.  
  117. # set save attack or heal
  118. if save:
  119. spell['save'] = spell_stats
  120. elif attack:
  121. spell['attack'] = spell_stats
  122. elif heal:
  123. spell['heal'] = spell_stats
  124.  
  125. # print spell_stats
  126. print spell
  127. filename = 'spells/%s.json' % (spell['name'].lower().replace(' ','-').replace('/','-'))
  128. print filename
  129.  
  130. f = open(filename,'w')
  131. json.dump(spell, f, separators=(',', ':'), indent=4)
  132. f.close()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement