Difference between revisions of "Ability/Script"

From Wildermyth Wiki
Line 9: Line 9:
import re
import re


directory = 'assets/data/aspects'
aspect_directory = 'assets/data/aspects'
theme_directory = 'assets/data/themes'
text_file = 'assets/text/aspects/aspects.properties'
text_file = 'assets/text/aspects/aspects.properties'
# make dictionary of localized names


aspectNames = {}
aspectNames = {}
Line 31: Line 34:
     elif len(key_split) == 2 and key_split[-1] == 'blurb':
     elif len(key_split) == 2 and key_split[-1] == 'blurb':
       aspectBlurbs[key_split[0]] = val[:-1]
       aspectBlurbs[key_split[0]] = val[:-1]
# read game version


with open('version.txt','r',encoding='utf8') as f:
with open('version.txt','r',encoding='utf8') as f:
   lines = f.readlines()
   lines = f.readlines()
   version = lines[0]
   version = lines[0]
# make list of abilities, by deck


decks = {'common':[],'warrior':[],'hunter':[],'mystic':[],'upgrade':[]}
decks = {'common':[],'warrior':[],'hunter':[],'mystic':[],'upgrade':[]}


aspectfiles = glob(directory + '/*')
aspectfiles = glob(aspect_directory + '/*')
for file in aspectfiles:
for file in aspectfiles:
   with open(file) as f:
   with open(file) as f:
Line 46: Line 53:
         if entry.get('info', {}).get('abilityDeckUsage') == deck:
         if entry.get('info', {}).get('abilityDeckUsage') == deck:
           decks[deck] += [entry]
           decks[deck] += [entry]
# move upgrades to other deck, if they upgrade that deck's ability


upgrades = []
upgrades = []
Line 65: Line 74:
      
      
decks['upgrade'] = upgrades
decks['upgrade'] = upgrades
# sort ability decks by localized name


for deck in decks:
for deck in decks:
   decks[deck] = sorted(decks[deck], key=lambda d: aspectNames[d['id']])  
   decks[deck] = sorted(decks[deck], key=lambda d: aspectNames[d['id']])  
 
# make dictionary of theme links
'''
themes = {}
themefiles = glob(theme_directory + '/*')
for file in themefiles:
  with open(file) as f:
    data = json.load(f)
    theme = data['id']
    for piece in data['pieces']:
      'themePiece_' + theme
     
    for entry in data:
      for deck in decks:
        if entry.get('info', {}).get('abilityDeckUsage') == deck:
          decks[deck] += [entry]
'''
# wiki blurb for each deck


deck_blurbs = {
deck_blurbs = {
Line 77: Line 106:
   }
   }


string = ''
# function to replace [tag]...[] or [tag]...[tag]
# with new...new, while respecting nested brackets


def replace_tag(tag,new,string):
def replace_tag(tag,new,string):
Line 96: Line 126:
         break
         break
   return string
   return string
# list of words to replace with links in the wiki


linkwords = [
linkwords = [
Line 120: Line 152:
   'grayplane',
   'grayplane',
   ]
   ]
# function to turn game-formatted ability blurb into wiki-formatted ability blurb


def parse(blurb):
def parse(blurb):
   out = blurb
   out = blurb
    
    
   out = replace_tag('b',"'''",out)
   out = replace_tag('b',"'''",out) # bold -> bold
   out = replace_tag('blue',"",out)
   out = replace_tag('blue',"",out) # blue -> plain
   out = replace_tag('gray',"",out)
   out = replace_tag('gray',"",out) # gray -> plain
    
    
   out = out.replace('<self>','Hero')
   out = out.replace('<self>','Hero')
   out = out.replace('<name>','Hero')
   out = out.replace('<name>','Hero')
    
    
   out = re.sub(r'\<int:(.*?)\>', 'x', out)
  ### TODO: rewrite these to appropriately respect nested brackets and braces
   out = re.sub(r'\<float:(.*?)\>', 'x', out)
 
   out = re.sub(r'\<int:(.*?)\>', 'x', out) # formula -> x
   out = re.sub(r'\<float:(.*?)\>', 'x', out) # formula -> x
 
  out = re.sub(r'\<mf:.*?/.*?/(.*?)\>', '\g<1>', out) # use they/them
    
    
   out = re.sub(r'\<mf:.*?/.*?/(.*?)\>', '\g<1>', out)
   # status effect -> link
   out = re.sub(r'\[:statusEffect\.(.*?)\](.*?)\[\]', '[[\g<1>|\g<2>]]', out)
   out = re.sub(r'\[:statusEffect\.(.*?)\](.*?)\[\]', '[[\g<1>|\g<2>]]', out)
   out = re.sub(r'\[statusEffect:(.*?)\](.*?)\[\]', '[[\g<1>|\g<2>]]', out)
   out = re.sub(r'\[statusEffect:(.*?)\](.*?)\[\]', '[[\g<1>|\g<2>]]', out)
 
  # assume any requirements are not met
   out = re.sub(r'\<self\..*?:.*?[^<]/(.*?)\>', '\g<1>', out)
   out = re.sub(r'\<self\..*?:.*?[^<]/(.*?)\>', '\g<1>', out)
   out = re.sub(r'\<self\..*?:.*?\>', '', out)
   out = re.sub(r'\<self\..*?:.*?\>', '', out)
   out = re.sub(r'\<test:.*?:(.*?[^<])/.*?\>', '\g<1>', out)
   out = re.sub(r'\<test:.*?:(.*?[^<])/.*?\>', '\g<1>', out)
   out = re.sub(r'\<test:.*?:.*?\>', '', out)
   out = re.sub(r'\<test:.*?:.*?\>', '', out)
 
  # leave out "(Currently ...)" note which is based on hero's current stats
   out = re.sub(r'\(Current.*?\)', '', out)
   out = re.sub(r'\(Current.*?\)', '', out)
    
    
   out = out.replace('\\n','<br />')
   ###
    
    
   for word in linkwords:
  out = out.replace('\\n','<br />') # newline -> newline
 
   for word in linkwords: # replace words with links
     out = out.replace(word,'[[%s]]'%word)
     out = out.replace(word,'[[%s]]'%word)
   return out
   return out
# build output string
string = ''


for deck in decks:
for deck in decks:
 
  # add deck blurb
   string += deck_blurbs[deck]
   string += deck_blurbs[deck]
 
  # add table headings
   if deck != 'upgrade':
   if deck != 'upgrade':
     string += '\n{| class="wikitable"\n! Name\n! Description\n|-\n'
     string += '\n{| class="wikitable"\n! Name\n! Description\n|-\n'
   else:
   else:
     string += '\n{| class="wikitable sortable"\n! Name\n! Requires one of\n! Description\n|-\n'
     string += '\n{| class="wikitable sortable"\n! Name\n! Requirement\n! Description\n|-\n'
   
  # add ability lines
   for entry in decks[deck]:
   for entry in decks[deck]:
   
    # add name
     name = aspectNames[entry['id']]
     name = aspectNames[entry['id']]
    blurb = aspectBlurbs[entry['id']]
   
     if name[-1] == '+':
     if name[-1] == '+':
       nameStr = '[[' + name[:-1] + ']]+'
       nameStr = '[[' + name[:-1] + ']]+'
Line 164: Line 218:
       nameStr = '[[' + name + ']]'
       nameStr = '[[' + name + ']]'
     nameStr = nameStr.replace('/',']]/[[')
     nameStr = nameStr.replace('/',']]/[[')
    string += '| %s\n'%(nameStr)
      
      
     string += '| %s\n'%(nameStr)
     # add requirements
     if deck == 'upgrade':
     if deck == 'upgrade':
       requirements = []
       requirements = []
      themes = []
      legs = {}
      arms = {}
       for req in entry.get('abilityRequiresOneAspectOf'):
       for req in entry.get('abilityRequiresOneAspectOf'):
         reqname = aspectNames[req]
         requirements += [req]
         reqname = reqname.replace('(','')
       
         reqname = reqname.replace(')','')
        # get associated info
         requirements += ['[[%s|%s]]'%(reqname,aspectNames[req])]
        theme = None
       string += '| %s\n'%(', '.join(requirements))
        if req.startswith('themePiece_'):
          theme = 'theme_' + req.split('_')[1]
          if req.endswith('leftArm') or req.endswith('rightArm'):
            if arms.get(theme): arms[theme] += 1
            else: arms[theme] = 1
          if req.endswith('leftLeg') or req.endswith('rightLeg'):
            if legs.get(theme): legs[theme] += 1
            else: legs[theme] = 1
        elif req.startswith('theme_'):
          theme = req
        themes += [theme]
     
      # start requirement string
      reqStr = ''
     
      # only precede with theme if there is only one
      onlyTheme = None
      if len(set(themes)) == 1 and themes[0] is not None:
        reqStr += '[[%s]]'%aspectNames[themes[0]]
        onlyTheme = themes[0]
     
      # compress requirements
      reqs = []
      for i,req in enumerate(requirements):
       
        # if requirement = theme, don't repeat it
        if onlyTheme is not None and aspectNames[req] == aspectNames[onlyTheme]:
          continue
          
        # combine 2 arms
        if (req.endswith('leftArm') or req.endswith('rightArm')) and arms[themes[i]] != 1:
          if arms.get(themes[i]) >= 2:
            reqname = re.sub(r'\(.*?\)', '(either)', aspectNames[req])
            arms[themes[i]] = -1
          elif arms.get(themes[i]) < 0:
            continue
       
        # combine 2 legs
         elif (req.endswith('leftLeg') or req.endswith('rightLeg')) and legs[themes[i]] != 1:
          if legs.get(themes[i]) >= 2:
            reqname = re.sub(r'\(.*?\)', '(either)', aspectNames[req])
            legs[themes[i]] = -1
          elif legs.get(themes[i]) < 0:
            continue
       
        else:
          reqname = aspectNames[req]
          
        # requirements don't need to link if the theme already will
        if onlyTheme is None:
          reqs += ['[[%s|%s]]'%(aspectNames[themes[i]],reqname)]
        else:
          reqs += ['%s'%(reqname)]
     
      # join requirements into our string
      if len(reqs) > 0:
        reqStr += ': '
        reqStr += ' or '.join(reqs)
       string += '| %s\n'%(reqStr)
   
    # add blurb
    blurb = aspectBlurbs[entry['id']]
     string += '| %s\n|-\n'%parse(blurb)
     string += '| %s\n|-\n'%parse(blurb)
   string += '|}\n\n'
 
  # close table
   string += '|}\n'
   string += '<small>Last updated [[%s]] using [[/Script|this script]].</small>\n'%version[:-1]
   string += '<small>Last updated [[%s]] using [[/Script|this script]].</small>\n'%version[:-1]
    
    
# write the final string
with open('abilityTable.txt', 'w') as f:
with open('abilityTable.txt', 'w') as f:
   f.write(string)</nowiki>
   f.write(string)</nowiki>
|}
|}

Revision as of 08:23, 5 March 2022

This is a Python script to generate the Ability tables. Copy the code in the box below into a text file named abilityTable.py (or whatever you want) inside the Wildermyth directory. Then run it by calling python abilityTable.py from the command line. It will create a text file named abilityTable.txt with the appropriate wiki-formatted content.