I extracted these from the XML definitions. Note that the values are different for the base game!
Just curious, how did you get all of that data from the xml and into tables?
Thanks!
Any chance of you (Stardock) putting this in the wiki?
I wrote a Python script to read it and output html. Let me try to post it here...
Sorry for the long messy post. The spoiler tags and the source code blocks don't seem to work for me.
import xml.etree.ElementTree as ET
import re
def parse_node(node):
'''
ElementTree indexes by position. Convert to indexing by name of attribute.
imp = {}
for child in node:
tag = child.tag.strip()
text = child.text.strip()
if len(text) > 0:
imp[tag] = text
else:
# get the list associated with this tag
if tag in imp:
attr_list = imp[tag]
attr_list = []
imp[tag] = attr_list
if len(child) > 0:
attr_list.append(parse_node(child)) # recursive call
return imp
def print_improvements(imps, out):
imps_dict = {}
for imp in imps:
imp_type = imp.get('ImprovementType')
if imp_type in imps_dict:
imps_dict[imp_type].append(imp)
imps_dict[imp_type] = [imp]
for k, v in imps_dict.iteritems():
if len(v) == 0: continue
out.write('<h4>%s</h4>\n' % pretty_name(k))
out.write('<table border="1">\n')
out.write(header_row() + '\n')
for imp in v:
out.write(print_improvement(imp))
out.write('</table>\n')
def get_all(node, label, sublabel):
if node.get(label) is None:
return
for el in node[label]: # list
if el.get(sublabel):
yield el[sublabel]
Columns:
Name & UpgradesFrom & Prereqs & Cost & Maintenance & Effects & LevelEffects & NeigbhbourBonus & Other
def header_row():
return '<tr><th>Name</th><th>Upgrades From</th><th>Prereqs</th><th>Cost</th><th>Maintenance</th><th>Effects</th><th>Level Effects</th><th>Adjacency Bonuses</th><th>Other</th></tr>'
def print_improvement(imp):
ret = '<tr>'
ret += '<td>%s</td>' % internal_name(imp)
ret += '<td>%s</td>' % upgrades_from(imp)
ret += '<td>%s</td>' % prereqs(imp)
ret += '<td>%s</td>' % cost(imp)
ret += '<td>%s</td>' % maintenance(imp)
ret += '<td>%s</td>' % effects(imp)
ret += '<td>%s</td>' % level_effects(imp)
ret += '<td>%s</td>' % neighbour_bonus(imp)
ret += '<td>%s</td>' % other_notes(imp)
ret += '</tr>'
return ret
replacement = {'MaxManufacturing': 'Production', 'Manufacturing': 'Social Production',
'GoodsAndServices': 'Morale', 'FoodIncome': 'Food', 'InfluencePerTurn':'Influence',
'ColonyGrossIncome': 'Income', 'CulturePerTurnMerciless': 'Malevolent',
'CulturePerTurnNeutral': 'Pragmatic', 'CulturePerTurnBenevolent': 'Benevolent',
'TradeRouteValueRaw': 'Trade Route Value'}
def pretty_name(name):
if name in replacement:
return replacement[name]
if name.endswith('Tech') or name.endswith('Cost'):
name = name[:-4]
if name.endswith('Ability'):
name = name[:-7]
name = re.sub("([A-Z])"," \g<0>", name)
name = name.replace('ofthe ', ' of the ').replace('of ', ' of ')
return name
def internal_name(imp):
return pretty_name(imp['InternalName'])
def upgrades_from(imp):
for el in get_all(imp, 'Prerequ', 'UpgradesFrom'):
return pretty_name(el)
return ''
def prereqs(imp):
ret = []
for el in get_all(imp, 'Prerequ', 'Techs'):
ret.append(pretty_name(el[0]['Option']))
for el in get_all(imp, 'Prerequ', 'RaceTrait'):
for subel in el:
ret.append('Race Trait: ' + pretty_name(subel['Option']))
for el in get_all(imp, 'Prerequ', 'Culture'):
ret.append('Ideology: ' + pretty_name(subel['Option']))
for el in get_all(imp, 'Prerequ', 'ColonySponsoringShipyard'):
if el == 'true':
ret.append('Sponsoring shipyard')
for el in get_all(imp, 'Preclusions', 'RaceTrait'):
ret.append('Race Trait: NOT ' + pretty_name(subel['Option']))
for el in get_all(imp, 'Preclusions', 'Improvement'):
ret.append('NOT ' + pretty_name(el))
return '<br/>'.join(ret)
def cost(imp):
ret = ''
for el in imp.get('Stats'):
if el.get('EffectType') == 'ManufacturingCost':
ret = el.get('Value')
# get all the resource costs
if imp.get('Stats') is None: return ''
if (el.get('EffectType') not in ['ManufacturingCost'] and el.get('EffectType').endswith('Cost')) \
or el.get('EffectType') == 'Credits':
if len(ret) > 0:
ret += '<br/>'
ret += stat_str(el)
def maintenance(imp):
if el.get('EffectType') == 'Maintenance':
return el.get('Value')
def effects(imp):
if imp.get('Stats') is not None:
if el.get('EffectType') not in ['Maintenance', 'ManufacturingCost'] and not el.get('EffectType').endswith('Cost') \
and not el.get('EffectType') == 'Credits':
if imp.get('Triggers') is not None:
for el in imp.get('Triggers'):
ret += trigger_str(el)
if imp.get('LandPercentageMin') is not None:
ret += 'Terraform: %d%% Land Minimum' % (float(imp.get('LandPercentageMin')) * 100)
def level_effects(imp):
if imp.get('LevelEffectStats') is not None:
for el in imp.get('LevelEffectStats'):
if el.get('EffectType') not in ['Maintenance', 'ManufacturingCost']:
if imp.get('LevelEffectTriggers') is not None:
for el in imp.get('LevelEffectTriggers'):
def neighbour_bonus(imp):
if imp.get('NeighborBonuses') is None: return ''
for el in imp.get('NeighborBonuses'):
bonus_type = pretty_name(el.get('GiveBonusToNeighborType'))
bonus_value = el.get('NeighborBonusValue')
ret += '%s %s' % (bonus_value, bonus_type)
def other_notes(imp):
# colony unique
if imp.get('IsColonyUnique') == 'true':
ret += 'Colony Unique <br/>'
if imp.get('IsIndestructible') == 'true':
ret += 'Indestructible <br/>'
# indestructible
def stat_str(el):
resource = pretty_name(el.get('EffectType'))
value = el.get('Value')
modifier = ''
if el.get('Scope') == 'Global':
modifier = 'Global '
if el['BonusType'] == 'Flat' or el['BonusType'] == 'OneTime':
return '%s %s%s' % (value, modifier, resource)
if el['BonusType'] == 'Multiplier':
return '%.1f%% %s%s' % ((float(value)*100), modifier, resource)
def trigger_str(el):
for subel in get_all(el, 'PerformAction', 'Action'):
if subel == 'GrantUnitType':
return 'Grants ' + el.get('PerformAction')[0].get('StringParam')
elif subel == 'AwardResearchAmount':
return el.get('PerformAction')[0].get('ValueParam') + ' Research Points'
return el.get('PerformAction')[0].get('Action')
for subel in el.get('Modifier'):
return stat_str(subel)
################################################################################
def write_improvements_html(f, out_f):
# read improvements
imps = []
tree = ET.parse(f)
for node in tree.getroot():
imp = parse_node(node)
#print imp
#exit()
imps.append(imp)
print len(imps), 'improvements'
out = open(out_f, 'w')
# separate wonders from non-wonders
wonders = [imp for imp in imps if imp.get('IsGalacticWonder') == 'true']
player_wonders = [imp for imp in imps if imp.get('IsPlayerWonder') == 'true']
non_wonders = [imp for imp in imps if imp not in wonders and imp not in player_wonders]
out.write('<html><body>\n')
out.write('<h2>Galactic Wonders</h2>')
print_improvements(wonders, out)
out.write('<h2>Player Wonders</h2>')
print_improvements(player_wonders, out)
out.write('<h2>Improvements</h2>')
print_improvements(non_wonders, out)
out.write('</body></html>')
out.close()
def write_starbase_html(f, out_f):
# read modules
print len(imps), 'modules'
out.write('<h2>Starbase Modules</h2>')
print_starbase(imps, out)
def print_starbase(imps, out):
imp_type = imp.get('SpecializationType')
out.write(header_row_module() + '\n')
out.write(print_module(imp))
def header_row_module():
return '<tr><th>Name</th><th>Upgrades From</th><th>Prereqs</th><th>Cost</th><th>Maintenance</th><th>Effects</th></tr>'
def print_module(imp):
def write_ship_html(f, out_f):
print len(imps), 'components'
out.write('<h2>Ship Components</h2>')
print_ship(imps, out)
#ShipComponent
def print_ship(imps, out):
imp_type = imp.get('Type')
if __name__ == '__main__':
f = 'ImprovementDefs.xml'
out_f = 'improvements.html'
write_improvements_html(f, out_f)
f = 'StarbaseModuleDefs.xml'
out_f = 'starbase.html'
write_starbase_html(f, out_f)
f = 'ShipComponentDefs.xml'
out_f = 'ship_components.html'
write_ship_html(f, out_f)
well if nothing else hopefully they can use this to double check the industrcutableness of a few buildings.
There are many great features available to you once you register, including:
Sign in or Create Account