wmlunits: Changed units forest structure to a network structure...

...for multiple units advancing to the same unit, and added some
sanity checks for units who can advance to themselves.
This commit is contained in:
Elias Pschernig 2008-04-25 14:16:36 +00:00
parent a59593c548
commit 9630080049
2 changed files with 62 additions and 43 deletions

View file

@ -286,6 +286,14 @@ class WesnothList:
auid = advance.strip()
if auid: unit.advance.append(auid)
# level
try:
level = int(self.get_unit_value(unit, "level"))
except TypeError:
level = 5
if level < 0: level = 5
unit.level = level
return len(newunits)
def find_unit_factions(self):
@ -341,28 +349,52 @@ class UnitForest:
"""
Add a new unit to the forest.
"""
self.lookup[un.id] = un
# First, we check if any of the new node's advancements already is in
# the tree. If so, attach it to the new node.
for cid in un.child_ids:
if cid in self.trees:
un.children.append(self.trees[cid])
self.lookup[cid].parent_ids.append(un.id)
del self.trees[cid]
def create_network(self):
"""
Assuming that each node which has been added to the tree only has a
valid list of children in unit.child_ids, also fill in unit.parent_ids
and update the unit.children shortcut.
"""
# Complete the network
for uid, u in self.lookup.items():
for cid in u.child_ids:
c = self.lookup.get(cid, None)
if not c: continue
u.children.append(c)
if not uid in c.parent_ids:
c.parent_ids.append(uid)
# Next, we check if the node is an advancement of an existing node. If
# so, add it there.
for rootnode in self.trees.values():
# Because multiple units might advance into this one, we do not
# stop after a successful insertion.
rootnode.try_add(un)
# Put all roots into the forest
for uid, u in self.lookup.items():
if not u.parent_ids:
self.trees[uid] = u
# Sanity check because some argGRRxxx addons have units who advance to
# themselves.
# Else, add a new tree with the new node as root.
self.trees[un.id] = un
def recurse(u, already):
already2 = already.copy()
for c in u.children[:]:
already2[c.id] = True
if c.id in already:
sys.stderr.write(
"Warning: Unit %s advances to unit %s in a loop.\n" %
(u.id, c.id))
sys.stderr.write(" Removing advancement %s.\n" % c.id)
u.children.remove(c)
for c in u.children:
recurse(c, already2)
for u in self.trees.values():
already = {u.id : True}
recurse(u, already)
def update_breadth(self):
def update(self):
self.create_network()
self.breadth = sum([x.update_breadth() for x in self.trees.values()])
return self.breadth
@ -386,17 +418,6 @@ class UnitNode:
self.parent_ids = []
self.child_ids.extend(unit.advance)
def try_add(self, un):
# A child of yours truly?
if un.id in self.child_ids:
self.children.append(un)
un.parent_ids.append(self.id)
return True
# A recursive child?
for child in self.children:
if child.try_add(un): return True
return False
def update_breadth(self):
if not self.children:
self.breadth = 1

View file

@ -89,7 +89,7 @@ class HTMLOutput:
def analyze_units(self, grouper):
"""
This takes all units belonging to a campaign, then groups them either
by race of faction, and creates an advancements tree out of it.
by race or faction, and creates an advancements tree out of it.
"""
# Build an advancement tree forest of all units.
@ -111,7 +111,7 @@ class HTMLOutput:
continue
forest.add_node(helpers.UnitNode(au))
units_added[auid] = au
forest.update_breadth()
forest.update()
# Partition trees by race/faction of first unit.
groups = {}
@ -148,12 +148,7 @@ class HTMLOutput:
def grid_place(nodes, x):
nodes.sort(by_name)
for node in nodes:
try:
level = int(self.wesnoth.get_unit_value(node.unit, "level"))
except TypeError:
level = 5
if level < 0: level = 5
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)
@ -207,12 +202,15 @@ class HTMLOutput:
# 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 = self.wesnoth.campaign_lookup.keys()
if i == 0:
cnames = [x for x in cnames if x in self.wesnoth.is_mainline_campaign]
else:
cnames = [x for x in cnames if not x in self.wesnoth.is_mainline_campaign]
cnames = cids[i]
cnames.sort()
for cname in cnames:
lang = self.isocode
@ -229,7 +227,7 @@ class HTMLOutput:
write(" <a title=\"%s\" href=\"../%s/%s.html\">%s</a><br/>\n" % (
campname, lang, cname, campabbrev))
if i == 0:
if i == 0 and cids[1]:
write("-<br/>\n")
write("</td>\n")
write("</tr>\n")
@ -251,7 +249,7 @@ class HTMLOutput:
for eraname, eid in eranames:
write(" <a title=\"%s\" href=\"../%s/%s.html\">%s</a><br/>" % (
eraname, lang, eid, abbrev(eraname)))
if i == 0:
if i == 0 and eids[1]:
write("-<br/>\n")
write("</td>\n")
write("</tr>\n")