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:
parent
a59593c548
commit
9630080049
2 changed files with 62 additions and 43 deletions
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Add table
Reference in a new issue