wesnoth/data/tools/wmlunits
2009-01-01 10:27:41 +00:00

1035 lines
36 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
#encoding: utf8
"""
wmlunits -- tool to output information on all units in HTML
Run without arguments to see usage.
"""
# Makes things faster on 32-bit systems
try: import psyco; psyco.full()
except ImportError: pass
import sys, os, re, glob, shutil, copy, urllib2
import wesnoth.wmldata as wmldata
import wesnoth.wmlparser as wmlparser
import wesnoth.wmltools as wmltools
sys.path.append(".")
import unit_tree.helpers as helpers
import unit_tree.animations as animations
html_header = '''
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel=stylesheet href=\"%(path)sstyle.css\" type=\"text/css\">
</head>
<body>'''.strip()
html_footer = '''
<div id="footer">
<p><a href="http://www.wesnoth.org/wiki/Wesnoth:Copyrights">Copyright</a> &copy; 2003-2009 The Battle for Wesnoth</p>
<p>Supported by <a href="http://www.jexiste.fr/">Jexiste</a></p>
</div>
</body></html>
'''.strip()
class GroupByRace:
def __init__(self, wesnoth, campaign):
self.wesnoth = wesnoth
self.campaign = campaign
def unitfilter(self, unit):
if not self.campaign: return True
return unit.campaign == self.campaign
def groups(self, unit):
return [unit.race]
def group_name(self, group):
if not group: return "None"
return group.get_text_val("plural_name")
class GroupByFaction:
def __init__(self, wesnoth, era):
self.wesnoth = wesnoth
self.era = era
def unitfilter(self, unit):
return self.era in unit.eras
def groups(self, unit):
return [x for x in unit.factions if x[0] == self.era]
def group_name(self, group):
era = self.wesnoth.era_lookup[group[0]]
faction = era.faction_lookup[group[1]]
name = faction.get_text_val("name")
name = name[name.rfind("=") + 1:]
name = era.get_text_val("name") + " / " + name
return name
class HTMLOutput:
def __init__(self, isocode, output, campaign, wesnoth, verbose = False):
self.isocode = isocode
self.output = output
self.campaign = campaign
self.verbose = verbose
self.target = "index.html"
self.wesnoth = wesnoth
self.forest = None
def get_translation(self, textdomain, key):
return self.wesnoth.parser.translations.get(textdomain, self.isocode,
key, key)
def analyze_units(self, grouper):
"""
This takes all units belonging to a campaign, then groups them either
by race or faction, and creates an advancements tree out of it.
"""
# Build an advancement tree forest of all units.
forest = self.forest = helpers.UnitForest()
units_added = {}
for uid, u in self.wesnoth.unit_lookup.items():
if grouper.unitfilter(u):
forest.add_node(helpers.UnitNode(u))
units_added[uid] = u
# Always add any child units, even if they have been filtered out..
while units_added:
new_units_added = {}
for uid, u in units_added.items():
for auid in u.advance:
if not auid in units_added:
try:
au = self.wesnoth.unit_lookup[auid]
except KeyError:
sys.stderr.write(
"Warning: Unit %s not found as advancement of %s\n" %
(auid, uid))
continue
forest.add_node(helpers.UnitNode(au))
new_units_added[auid] = au
units_added = new_units_added
forest.update()
# Partition trees by race/faction of first unit.
groups = {}
breadth = 0
for tree in forest.trees.values():
u = tree.unit
ugroups = grouper.groups(u)
for group in ugroups:
groups[group] = groups.get(group, []) + [tree]
breadth += tree.breadth
thelist = groups.keys()
thelist.sort()
rows_count = breadth + len(thelist)
# Create empty grid.
rows = []
for j in range(rows_count):
column = []
for i in range(6):
column.append((1, 1, None))
rows.append(column)
# Sort advancement trees by name of first unit and place into the grid.
def by_name(t1, t2):
u1 = t1.unit
u2 = t2.unit
u1name = u1.get_text_val("name")
u2name = u2.get_text_val("name")
return cmp(u1name, u2name)
def grid_place(nodes, x):
nodes.sort(by_name)
for node in nodes:
level = node.unit.level
rows[x][level] = (1, node.breadth, node)
for i in range(1, node.breadth):
rows[x + i][level] = (0, 0, node)
grid_place(node.children, x)
x += node.breadth
return x
x = 0
for group in thelist:
node = helpers.GroupNode(group)
node.name = grouper.group_name(group)
rows[x][0] = (6, 1, node)
for i in range(1, 6):
rows[x][i] = (0, 0, None)
nodes = groups[group]
x += 1
x = grid_place(nodes, x)
self.unitgrid = rows
def write_navbar(self):
def write(x): self.output.write(x)
def _(x): return self.get_translation("wesnoth", x)
languages = find_languages()
langlist = languages.keys()
langlist.sort()
write("""
<div class="header">
<a href="http://www.wesnoth.org">
<img src="../wesnoth-logo.jpg" alt="Wesnoth logo"/>
</a>
</div>
<div class="topnav">
<a href="../index.html">Wesnoth Units database</a>
</div>
""")
write("<table class=\"navbar\">")
write("<tr>\n")
def abbrev(name):
abbrev = name[0]
word_seperators = [" ", "_", "+", "(", ")"]
for i in range(1, len(name)):
if name[i] in ["+", "(", ")"] or name[i - 1] in word_seperators and name[i] not in word_seperators:
abbrev += name[i]
return abbrev
# Campaigns
x = _("TitleScreen button^Campaign")
write("<th>%s</th></tr><tr><td>" % x)
cids = [[], []]
for cid in self.wesnoth.campaign_lookup.keys():
if cid in self.wesnoth.is_mainline_campaign:
cids[0].append(cid)
else:
cids[1].append(cid)
for i in range(2):
cnames = cids[i]
cnames.sort()
for cname in cnames:
lang = self.isocode
if cname == "mainline":
campname = self.get_translation("wesnoth", "Multiplayer")
campabbrev = campname
else:
campname = self.wesnoth.campaign_lookup[cname].get_text_val("name")
if not campname:
campname = cname
campabbrev = self.wesnoth.campaign_lookup[cname].get_text_val("abbrev")
if not campabbrev:
campabbrev = abbrev(campname)
write(" <a title=\"%s\" href=\"../%s/%s.html\">%s</a><br/>\n" % (
campname, lang, cname, campabbrev))
if i == 0 and cids[1]:
write("-<br/>\n")
write("</td>\n")
write("</tr>\n")
# Eras
write("<tr>\n")
x = _("Era")
write("<th>%s</th></tr><tr><td>" % x)
eids = [[], []]
for eid in self.wesnoth.era_lookup.keys():
if eid in self.wesnoth.is_mainline_era:
eids[0].append(eid)
else:
eids[1].append(eid)
for i in range(2):
eranames = [(self.wesnoth.era_lookup[eid].get_text_val("name"),
eid) for eid in eids[i]]
eranames.sort()
for eraname, eid in eranames:
write(" <a title=\"%s\" href=\"../%s/%s.html\">%s</a><br/>" % (
eraname, lang, eid, abbrev(eraname)))
if i == 0 and eids[1]:
write("-<br/>\n")
write("</td>\n")
write("</tr>\n")
# Races
if self.campaign == "mainline":
write("<tr>\n")
x = _("Race")
write("<th>%s</th></tr><tr><td>" % x)
write("<a href=\"mainline.html\">%s</a><br/>\n" % (
self.get_translation("wesnoth-editor", "all")))
racenames = {}
for u in self.wesnoth.unit_lookup.values():
if u.campaign != self.campaign: continue
race = u.race
racename = race.get_text_val("plural_name")
racenames[racename] = race.get_text_val("id")
racenames = racenames.items()
racenames.sort()
for racename, rid in racenames:
write(" <a href=\"mainline.html#%s\">%s</a><br/>" % (
racename, racename))
write("</td>\n")
write("</tr>\n")
# Languages
write("<tr>\n")
x = _("Language")
write("<th>%s</th></tr><tr><td>" % x)
for lang in langlist:
labb = lang
underscore = labb.find("_")
if underscore > 0: labb = labb[:underscore]
write(" <a title=\"%s\" href=\"../%s/%s\">%s</a><br/>\n" % (
languages[lang], lang, self.target,
labb))
write("</td>\n")
write("</tr>\n")
write("</table>\n")
def pic(self, u, x):
image = self.wesnoth.get_unit_value(x, "image")
if not image:
if x.name == "female":
baseunit = self.wesnoth.get_base_unit(u)
if baseunit:
female = baseunit.get_first("female")
return self.pic(u, female)
sys.stderr.write(
"Warning: Missing image for unit %s(%s).\n" % (
u.get_text_val("id"), x.name))
return None
picname = image_collector.add_image(u.campaign, image)
image = os.path.join("../pics", picname)
return image
def get_abilities(self, u):
anames = []
already = {}
for abilities in u.get_all("abilities"):
try: c = abilities.children()
except AttributeError: c = []
for ability in c:
id = ability.get_text_val("id")
if id in already: continue
already[id] = True
name = ability.get_text_val("name")
if not name: name = id
if not name: name = ability.name
anames.append(name)
return anames
def get_recursive_attacks(self, this_unit):
def copy_attributes(copy_from, copy_to):
for c in copy_from.children():
if isinstance(c, wmldata.DataText):
copy_to.set_text_val(c.name, c.data)
# Use attacks of base_units as base, if we have one.
base_unit = self.wesnoth.get_base_unit(this_unit)
attacks = []
if base_unit:
attacks = copy.deepcopy(self.get_recursive_attacks(base_unit))
base_attacks_count = len(attacks)
for i, attack in enumerate(this_unit.get_all("attack")):
# Attack merging is order based.
if i < base_attacks_count:
copy_attributes(attack, attacks[i])
else:
attacks.append(attack)
return attacks
def write_units(self):
def write(x): self.output.write(x)
def _(x): return self.get_translation("wesnoth", x)
rows = self.unitgrid
write("<table class=\"units\">\n")
write("<colgroup>")
for i in range(6):
write("<col class=\"col%d\" />" % i)
write("</colgroup>")
pic = image_collector.add_image("mainline",
"../../../images/misc/leader-crown.png")
crownimage = os.path.join("../pics", pic)
ms = None
for row in range(len(rows)):
write("<tr>\n")
for column in range(6):
hspan, vspan, un = rows[row][column]
if vspan:
attributes = ""
if hspan == 1 and vspan == 1:
pass
elif hspan == 1:
attributes += " rowspan=%d" % vspan
elif vspan == 1:
attributes += " colspan=%d" % hspan
if un and isinstance(un, helpers.GroupNode):
# Find the current multiplayer side so we can show the
# little crowns..
ms = None
try:
eid, fid = un.data
era = self.wesnoth.era_lookup[eid]
ms = era.faction_lookup[fid]
except TypeError:
pass
racename = un.name
attributes += " class=\"raceheader\""
write("<td%s>" % attributes)
write("<a name=\"%s\">%s</a>" % (racename, racename))
write("</td>\n")
elif un:
u = un.unit
attributes += " class=\"unitcell\""
write("<td%s>" % attributes)
uid = u.get_text_val("id")
name = self.wesnoth.get_unit_value(u, "name")
cost = self.wesnoth.get_unit_value(u, "cost")
hp = self.wesnoth.get_unit_value(u, "hitpoints")
mp = self.wesnoth.get_unit_value(u, "movement")
xp = self.wesnoth.get_unit_value(u, "experience")
level = self.wesnoth.get_unit_value(u, "level")
crown = ""
if ms:
if un.id in ms.units:
crown = u""
if un.id in ms.is_leader:
crown = u""
link = "../%s/%s.html" % (self.isocode, uid)
write("<div class=\"i\"><a href=\"%s\" title=\"id=%s\">%s</a>" % (
link, uid, u""))
write("</div>")
write("<div class=\"l\">L%s%s</div>" % (level, crown))
write("<a href=\"%s\">%s</a><br/>" % (link, name))
write('<div class="pic">')
image = self.pic(u, u)
write('<a href=\"%s\">' % link)
if crown == u"":
write('<div style="background: url(%s)">' % image)
write('<img src="%s" alt="(image)" />' % crownimage)
write("</div>")
else:
write('<img src="%s" alt="(image)" />' % image)
write('</a>\n</div>\n')
write("<div class=\"attributes\">")
write("%s%s<br />" % (
self.get_translation("wesnoth", "Cost: "), cost))
write("%s%s<br />" % (
self.get_translation("wesnoth", "HP: "), hp))
write("%s%s<br />" % (
self.get_translation("wesnoth", "MP: "), mp))
write("%s%s<br />" % (
self.get_translation("wesnoth", "XP: "), xp))
# Write info about abilities.
anames = self.get_abilities(u)
if anames:
write("\n<div style=\"clear:both\">")
write(", ".join(anames))
write("</div>")
# Write info about attacks.
write("\n<div style=\"clear:both\">")
attacks = self.get_recursive_attacks(u)
for attack in attacks:
n = attack.get_text_val("number")
x = attack.get_text_val("damage")
x = "%s - %s" % (x, n)
write("%s " % x)
r = attack.get_text_val("range")
t = attack.get_text_val("type")
write("%s (%s)" % (_(r), _(t)))
s = []
specials = attack.get_first("specials")
if specials:
for special in specials.children():
sname = special.get_text_val("name")
if sname:
s.append(sname)
s = ", ".join(s)
write(" (%s)" % s)
write("<br />")
write("</div>")
write("</div>")
write("</td>\n")
else:
write("<td class=\"empty\"></td>")
write("</tr>\n")
write("</table>\n")
def write_units_tree(self, grouper, title):
self.output.write(html_header % {"path" : "../"})
self.analyze_units(grouper)
self.write_navbar()
self.output.write("<h1>%s</h1>" % title)
self.write_units()
self.output.write(html_footer)
def write_unit_report(self, output, unit):
def write(x): self.output.write(x)
def _(x): return self.get_translation("wesnoth", x)
def find_attr(what, key):
if unit.movetype:
mtx = unit.movetype.get_first(what)
mty = None
if mtx: mty = mtx.get_text_val(key)
x = unit.get_first(what)
y = None
if x: y = x.get_text_val(key)
if y:
return True, y
if unit.movetype and mty != None:
return False, mty
return False, "-"
self.output = output
write(html_header % {"path" : "../"})
self.write_navbar()
# Write unit name, picture and description.
uid = unit.get_text_val("id")
uname = self.wesnoth.get_unit_value(unit, "name")
display_name = uname
female = unit.get_first("female")
if female:
fname = female.get_text_val("name")
if fname and fname != uname:
display_name += "<br/>" + fname
write("<h1>%s</h1>\n" % display_name)
write('<div class="pic">')
if female:
mimage = self.pic(unit, unit)
fimage = self.pic(unit, female)
if not fimage: fimage = mimage
write('<img src="%s" alt="(image)" />\n' % mimage)
write('<img src="%s" alt="(image)" />\n' % fimage)
else:
image = self.pic(unit, unit)
write('<img src="%s" alt="(image)" />\n' % image)
write('</div>\n')
description = self.wesnoth.get_unit_value(unit, "description")
# TODO: what is unit_description?
if not description: description = unit.get_text_val("unit_description")
if not description: description = "-"
write("<p>%s</p>\n" % __import__('re').sub("\n","\n<br />", description) )
# Base info.
hp = self.wesnoth.get_unit_value(unit, "hitpoints")
mp = self.wesnoth.get_unit_value(unit, "movement")
xp = self.wesnoth.get_unit_value(unit, "experience")
level = self.wesnoth.get_unit_value(unit, "level")
alignment = self.wesnoth.get_unit_value(unit, "alignment")
write("<table class=\"unitinfo\">\n")
write("<tr>\n")
write("<th>%s" % _("Advances from: "))
write("</th><td>\n")
for pid in self.forest.get_parents(uid):
punit = self.wesnoth.unit_lookup[pid]
if unit.campaign == "mainline" and punit.campaign != "mainline":
continue
link = "../%s/%s.html" % (self.isocode, pid)
name = self.wesnoth.get_unit_value(punit, "name")
write("\n<a href=\"%s\">%s</a>" % (link, name))
write("</td>\n")
write("</tr><tr>\n")
write("<th>%s" % self.get_translation("wesnoth", "Advances to: "))
write("</th><td>\n")
for cid in self.forest.get_children(uid):
link = "../%s/%s.html" % (self.isocode, cid)
try:
cunit = self.wesnoth.unit_lookup[cid]
if unit.campaign == "mainline" and cunit.campaign != "mainline":
continue
name = self.wesnoth.get_unit_value(cunit, "name")
except KeyError:
sys.stderr.write("Warning: Unit %s not found.\n" % cid)
name = cid
if unit.campaign == "mainline": continue
write("\n<a href=\"%s\">%s</a>" % (link, name))
write("</td>\n")
write("</tr>\n")
for val, text in [
("cost", _("Cost: ")),
("hitpoints", _("HP: ")),
("movement", _("Movement") + ": "),
("experience", _("XP: ")),
("level", _("Level") + ": "),
("alignment", _("Alignment: ")),
("id", "ID")]:
write("<tr>\n")
write("<th>%s</th>" % text)
x = self.wesnoth.get_unit_value(unit, val)
if val == "alignment": x = self.get_translation("wesnoth", x)
write("<td>%s</td>" % x)
write("</tr>\n")
# Write info about abilities.
anames = self.get_abilities(unit)
write("<tr>\n")
write("<th>%s</th>" % _("Abilities: "))
write("<td>" + (", ".join(anames)) + "</td>")
write("</tr>\n")
write("</table>\n")
# Write info about attacks.
write("<table class=\"unitinfo\">\n")
attacks = self.get_recursive_attacks(unit)
for attack in attacks:
write("<tr>")
aid = attack.get_text_val("name")
aname = attack.get_text_val("description")
icon = attack.get_text_val("icon")
if not icon:
icon = "attacks/%s.png" % aid
picname, error = image_collector.add_image_check(unit.campaign, icon)
if error:
sys.stderr.write("Error: No attack icon '%s' found for '%s'.\n" % (
icon, uid))
icon = os.path.join("../pics", picname)
write("<td><img src=\"%s\" alt=\"(image)\"/></td>" % icon)
write("<td>%s" % aname)
t = attack.get_text_val("type")
write("<br/>%s</td>" % self.get_translation("wesnoth", t))
n = attack.get_text_val("number")
x = attack.get_text_val("damage")
x = "%s - %s" % (x, n)
write("<td>%s" % x)
r = attack.get_text_val("range")
write("<br/>%s</td>" % self.get_translation("wesnoth", r))
s = []
specials = attack.get_first("specials")
if specials:
for special in specials.children():
sname = special.get_text_val("name")
if sname:
s.append(sname)
else:
sys.stderr.write(
"Warning: Weapon special %s has no name for %s.\n" % (
special.name, uid))
s = "<br/>".join(s)
write("<td>%s</td>" % s)
write("</tr>")
write("</table>\n")
# Write info about resistances.
resistances = [
"blade",
"pierce",
"impact",
"fire",
"cold",
"arcane"]
write("<table class=\"unitinfo\">\n")
write("<tr>\n")
write("<th colspan=\"2\">%s</th>\n" %
self.get_translation("wesnoth", "Resistances: "))
write("</tr>\n")
for rid in resistances:
special, r = find_attr("resistance", rid)
if r == "-": r = 0
try: r = "%d%%" % (100 - int(r))
except ValueError:
sys.stderr.write("Warning: Invalid resistance %s for %s.\n" % (
r, uid))
rcell = "td"
if special: rcell += ' class="special"'
write("<tr>\n")
write("<th>%s</th><td>%s</td>\n" % (
self.get_translation("wesnoth", rid), r))
write("</tr>\n")
write("</table>\n")
# Write info about movement costs and terrain defense.
write("<table class=\"unitinfo\">\n")
write("<tr>\n")
write("<th>%s</th><th>%s</th><th>%s</th>\n" % (
_("Terrain"), _("Movement Cost"), _("Defense") ))
write("</tr>\n")
terrains = self.wesnoth.terrain_lookup
terrainlist = []
for tid, t in terrains.items():
if tid in ["off_map", "fog", "shroud"]: continue
if t.get_first("aliasof"): continue
name = t.get_text_val("name")
terrainlist.append((name, tid))
terrainlist.sort()
for tname, tid in terrainlist:
not_from_race, c = find_attr("movement_costs", tid)
ccell = "td"
if c == "99": ccell += ' class="grayed"'
dcell = "td"
not_from_race, d = find_attr("defense", tid)
if d == "-": d = 0
try: d = "%d%%" % (100 - int(d))
except ValueError:
sys.stderr.write("Warning: Invalid defense %s for %s.\n" % (
d, uid))
write("<tr>\n")
write("<td>%s</td><%s>%s</td><%s>%s</td>\n" % (
tname, ccell, c, dcell, d))
write("</tr>\n")
write("</table>\n")
write(html_footer)
languages_found = {}
def find_languages():
"""
Returns a dictionary mapping isocodes to languages.
"""
global languages
if languages_found: return languages_found
parser = wmlparser.Parser(datadir)
WML = wmldata.DataSub("WML")
parser.parse_text("{languages}\n")
parser.parse_top(WML)
for locale in WML.get_all("locale"):
isocode = locale.get_text_val("locale")
name = locale.get_text_val("name")
languages_found[isocode] = name
return languages_found
class MyFile:
"""
I don't understand why this is needed..
"""
def __init__(self, filename, mode):
self.f = open(filename, mode)
def write(self, x):
x = x.encode("utf8")
self.f.write(x)
def close(self):
self.f.close()
def generate_campaign_report(out_path, isocode, campaign, wesnoth):
print "Generating report for %s_%s." % (isocode, campaign)
path = os.path.join(out_path, isocode )
if not os.path.isdir(path): os.mkdir(path)
output = MyFile(os.path.join(path, "%s.html" % campaign), "w")
html = HTMLOutput(isocode, output, campaign, wesnoth)
html.target = "%s.html" % campaign
grouper = GroupByRace(wesnoth, campaign)
if campaign == "mainline":
title = html.get_translation("wesnoth", "Multiplayer")
else:
title = wesnoth.campaign_lookup[campaign].get_text_val("name")
if not title:
title = campaign
html.write_units_tree(grouper, title)
def generate_era_report(out_path, isocode, eid, wesnoth):
print "Generating report for %s_%s." % (isocode, eid)
path = os.path.join(out_path, isocode)
if not os.path.isdir(path): os.mkdir(path)
era = wesnoth.era_lookup[eid]
ename = era.get_text_val("name")
output = MyFile(os.path.join(path, "%s.html" % eid), "w")
html = HTMLOutput(isocode, output, eid, wesnoth)
html.target = "%s.html" % eid
grouper = GroupByFaction(wesnoth, eid)
title = ename
html.write_units_tree(grouper, title)
def generate_single_unit_reports(out_path, isocode, wesnoth):
odir = os.path.join(out_path, isocode)
if not os.path.isdir(odir):
os.mkdir(odir)
html = HTMLOutput(isocode, None, "units", wesnoth)
grouper = GroupByRace(wesnoth, None)
html.analyze_units(grouper)
for uid, unit in wesnoth.unit_lookup.items():
output = MyFile(os.path.join(odir, "%s.html" % uid), "w")
html.target = "%s.html" % uid
html.write_unit_report(output, unit)
def write_index(out_path):
output = MyFile(os.path.join(out_path, "index.html"), "w")
output.write("""
<html><head>
<meta http-equiv="refresh" content="0;url=C/mainline.html">
</head>
<body>
<a href="C/mainline.html">Redirecting to Wesnoth units database...</a>
</body>
</html>
""")
def copy_images():
if not options.nocopy:
print "Copying files."
image_collector.copy_and_color_images(options.output)
shutil.copy2(os.path.join("data", "tools/unit_tree/style.css"), options.output)
for grab in [
"http://www.wesnoth.org/mw/skins/glamdrol/headerbg.jpg",
"http://www.wesnoth.org/mw/skins/glamdrol/wesnoth-logo.jpg",
"http://www.wesnoth.org/mw/skins/glamdrol/navbg.png"]:
local = os.path.join(options.output, grab[grab.rfind("/") + 1:])
if not os.path.exists(local):
print "Fetching", grab
url = urllib2.urlopen(grab)
file(local, "w").write(url.read())
def output(isocode):
"""
We output:
* All mainline units sorted by race
* Each mainline era's units sorted by faction
* Each mainline campaign's units sorted by race
* Each addon era's units sorted by faction
* Each addon campaign's units sorted by race
"""
print "WML parser language reset to %s." % isocode
stuff = helpers.WesnothList(isocode, datadir, userdir, transdir)
# Parse some stuff we may need.
print "Parsing terrains ...",
n = stuff.add_terrains()
print "%d terrains found." % n
print "Parsing mainline eras ...",
n = stuff.add_mainline_eras()
print "%d mainline eras found." % n
stuff.is_mainline_era = {}
for c in stuff.era_lookup.keys():
stuff.is_mainline_era[c] = True
print "Parsing mainline campaigns ...",
n = stuff.add_mainline_campaigns()
print "%d mainline campaigns found." % n
stuff.is_mainline_campaign = {}
for c in stuff.campaign_lookup.keys():
stuff.is_mainline_campaign[c] = True
# Parse all unit data
# This reads in units.cfg, giving us all the mainline units.
print "Parsing mainline units ...",
sys.stdout.flush()
WML = stuff.parser.parse("{core/units.cfg}")
n = stuff.add_units(WML, "mainline")
print n, "mainline units found."
# Now we read each mainline campaign in turn to get its units.
cnames = stuff.campaign_lookup.keys()
for cname in cnames:
print "Parsing %s units ..." % cname,
sys.stdout.flush()
campaign = stuff.campaign_lookup[cname]
define = campaign.get_text_val("define")
WML = stuff.parser.parse("""
#define %s\n#enddef
{campaigns}""" % define,
ignore_macros = lambda x: x.find("/scenarios") == -1)
n = stuff.add_units(WML, cname)
image_collector.add_binary_pathes_from_WML(cname, WML)
print n, "units found."
sys.stderr.flush()
print "Parsing addons ...",
sys.stdout.flush()
n = stuff.add_addons(image_collector)
print "%d units found." % n
# Now we read each addon campaign in turn to get its units.
cnames = stuff.campaign_lookup.keys()
for cname in cnames:
if cname in stuff.is_mainline_campaign: continue
campaign = stuff.campaign_lookup[cname]
print "Parsing %s units ..." % cname,
sys.stdout.flush()
define = campaign.get_text_val("define")
WML = stuff.parser.parse("""
#define %s\n#enddef
{~campaigns}""" % define,
ignore_macros = lambda x: x.find("/scenarios") == -1)
n = stuff.add_units(WML, cname)
image_collector.add_binary_pathes_from_WML(cname, WML)
print n, "units found."
stuff.find_unit_factions()
# Report generation
if not os.path.isdir(options.output):
os.mkdir(options.output)
write_index(options.output)
campaigns = stuff.campaign_lookup.keys()
generate_campaign_report(options.output, isocode, "mainline", stuff)
for campaign in campaigns:
generate_campaign_report(options.output, isocode, campaign, stuff)
for eid in stuff.era_lookup.keys():
generate_era_report(options.output, isocode, eid, stuff)
# Single unit reports.
generate_single_unit_reports(options.output, isocode, stuff)
return stuff
if __name__ == '__main__':
global options
global image_collector
import optparse
op = optparse.OptionParser()
op.add_option("-l", "--language", default = "all",
help = "Specify a language.")
op.add_option("-o", "--output",
help = "Specify output directory.")
op.add_option("-n", "--nocopy", action = "store_true",
help = "No copying of files.")
op.add_option("-d", "--datadir",
help = "Specify Wesnoth's data to use. Default is to search current "+\
"directory upwards.")
op.add_option("-u", "--userdir",
help = "Specify user data dir to use, which is automatically scanned "+\
"for addons. For example -u ~/.wesnoth/data")
op.add_option("-t", "--transdir",
help = "Specify the directory which has a po subfolder for translations. "+\
"(Defaults to the current directory.)")
options, args = op.parse_args()
if not options.output:
op.print_help()
sys.exit(-1)
options.output = os.path.expanduser(options.output)
if not options.datadir:
#wmltools.pop_to_top("wmlunits")
datadir = os.getcwd() + "/data"
else:
datadir = options.datadir
userdir = options.userdir
if options.transdir:
transdir = options.transdir
else:
transdir = os.getcwd()
if options.language == "all":
languages = find_languages().keys()
languages.sort()
else:
languages = [options.language]
image_collector = helpers.ImageCollector(datadir, userdir)
once_without_translation = False
for isocode in languages:
wesnoth = output(isocode)
if not once_without_translation:
copy_images()
once_without_translation = True
for u in wesnoth.unit_lookup.values():
r = u.race
if r: r = r.get_text_val("id", "none")
else: r = "none"
# Store rid and id for each units so we have it easier
u.rid = r
u.id = u.get_text_val("id")
# Write a list with all unit ids, just for fun.
uids = wesnoth.unit_lookup.keys()
def by_race(u1, u2):
r = cmp(wesnoth.unit_lookup[u1].rid,
wesnoth.unit_lookup[u2].rid)
if r == 0: r = cmp(u1, u2)
return r
uids.sort(by_race)
race = None
f = MyFile(os.path.join(options.output, "uids.html"), "w")
f.write("<html><body>")
for uid in uids:
u = wesnoth.unit_lookup[uid]
if u.race != race:
if race != None: f.write("</ul>")
f.write("<p>%s</p>\n" % u.rid)
f.write("<ul>")
race = u.race
f.write("<li>%s</li>\n" % uid)
f.write("</ul>")
f.write("</body></html>")
f.close()
# Write animation statistics
f = MyFile(os.path.join(options.output, "animations.html"), "w")
animations.write_table(f, wesnoth)
f.close()