self.name = name
self.kind = kind
self.droplevel = 0
- self.upgrade = None
-
- def is_upgrade_for(self, other):
- return self.kind==other.kind and self.droplevel>other.droplevel
+ self.mods = {}
+ self.upgrades = {"attrs":None, "mods":None}
+
+ def is_compatible(self, other):
+ return self.kind==other.kind
+
+ def compare_mods(self, other):
+ result = 0
+ for n, v in self.mods.items():
+ ov = other.mods.get(n, 0)
+ if v<ov:
+ return -1
+ elif v>ov:
+ result = 1
+
+ for on, ov in other.mods.items():
+ v = self.mods.get(on, 0)
+ if v<ov:
+ return -1
+ elif v>ov:
+ result = 1
+
+ return result
+
+ def compare_attrs(self, other):
+ return 0
+
+ def check_upgrade(self, other):
+ if self.droplevel<=other.droplevel:
+ return
+ if not self.is_compatible(other):
+ return
+
+ mods = self.compare_mods(other)
+ attrs = self.compare_attrs(other)
+
+ if not other.upgrades["mods"]:
+ if mods>0 or (mods==0 and attrs>0):
+ other.upgrades["mods"] = self
+ if not other.upgrades["attrs"]:
+ if attrs>0 or (attrs==0 and mods>0):
+ other.upgrades["attrs"] = self
class Armor(Item):
def __init__(self, name, kind):
self.evasion = 0
self.energy_shield = 0
- def is_upgrade_for(self, other):
+ def is_compatible(self, other):
if (self.armor!=0)!=(other.armor!=0):
return False
if (self.evasion!=0)!=(other.evasion!=0):
if (self.energy_shield!=0)!=(other.energy_shield!=0):
return False
- return super(Armor, self).is_upgrade_for(other)
+ return super(Armor, self).is_compatible(other)
+
+ def compare_attrs(self, other):
+ if self.armor<other.armor:
+ return -1
+ if self.evasion<other.evasion:
+ return -1
+ if self.energy_shield<other.energy_shield:
+ return -1
+
+ if self.armor>other.armor:
+ return 1
+ if self.evasion>other.evasion:
+ return 1
+ if self.energy_shield>other.energy_shield:
+ return 1
+
+ return 0
class Weapon(Item):
def __init__(self, name, kind):
self.speed = 0
self.dps = 0
+ def compare_attrs(self, other):
+ if self.dps<other.dps:
+ return -1
+ if self.dps>other.dps:
+ return 1
+
+ return 0
+
class ItemDataParser(html.parser.HTMLParser):
def __init__(self):
super(ItemDataParser, self).__init__()
self.in_items_table = False
self.column = 0
self.in_cell = False
- self.ignore_row = False
self.items = {}
self.current_item = None
self.in_heading = False
self.headings = []
self.current_heading = None
+ self.mod_row = False
+ self.mod_names = []
+ self.mod_index = 0
def handle_starttag(self, tag, attrs):
if tag=="table":
if n=="class" and v=="itemDataTable":
self.in_items_table = True
elif tag=="tr":
- self.ignore_row = False
+ self.mod_row = False
for n, v in attrs:
if n=="class" and v.endswith("_mod"):
- self.ignore_row = True
+ self.mod_row = True
self.column = 0
- self.current_item = None
+ if not self.mod_row:
+ self.current_item = None
+ self.mod_names = []
elif tag=="td":
self.column += 1
self.in_cell = True
elif tag=="td":
self.in_cell = False
elif tag=="tr":
- if self.current_item:
+ if self.current_item and self.mod_row:
for it in self.items.values():
- if not it.upgrade and self.current_item.is_upgrade_for(it):
- it.upgrade = self.current_item
- break
+ self.current_item.check_upgrade(it)
elif tag=="h1":
self.in_heading = False
def handle_data(self, data):
data = data.strip()
+ if not data:
+ return
+
if self.in_heading:
self.current_heading = data
self.headings.append(self.current_heading)
- elif self.in_items_table and self.in_cell and data and not self.ignore_row:
- if self.column==2:
- self.current_item = self.create_item(data, self.current_heading)
- self.items[data] = self.current_item
- elif self.column==3:
- self.current_item.droplevel = int(data)
- elif self.column>=4:
- self.handle_value(self.column, data)
+ elif self.in_items_table and self.in_cell:
+ if self.mod_row:
+ if self.column==1:
+ self.mod_names.append(data)
+ self.mod_index = 0
+ elif self.column==2:
+ if " to " in data:
+ value = int(data.split(" to ", 1)[1])
+ else:
+ value = int(data)
+ name = self.mod_names[self.mod_index]
+ if name!="From Armour Movement Speed +%":
+ self.current_item.mods[name] = value
+ self.mod_index += 1
+ else:
+ if self.column==2:
+ self.current_item = self.create_item(data, self.current_heading)
+ self.items[data] = self.current_item
+ elif self.column==3:
+ self.current_item.droplevel = int(data)
+ elif self.column>=4:
+ self.handle_value(self.column, data)
def create_item(self, name, kind):
pass
elif column==6:
self.current_item.dps = float(data)
+def get_upgrade_level(item, steps):
+ level = 0
+ for p in item.upgrades.keys():
+ upgrade = item
+ for i in range(steps):
+ upgrade = upgrade.upgrades.get(p)
+ if not upgrade:
+ return 0
+ level = max(level, upgrade.droplevel)
+ return level
+
def write_best_category(out, prefix, items, steps):
best = ["best", "second"]
out.write('category "{}.{}_at_level"\n'.format(prefix, best[steps-1]))
out.write("{\n\tor\n\t{\n")
for it in items:
- upgrade = it
- for k in range(steps):
- upgrade = upgrade.upgrade
- if not upgrade:
- break
+ upgrade_level = get_upgrade_level(it, steps)
out.write("\t\tand\n\t\t{\n")
- if upgrade:
+ if upgrade_level:
out.write('\t\t\tbase_type "{}";\n'.format(it.name))
- out.write("\t\t\titem_level {} {};\n".format(it.droplevel, upgrade.droplevel-1))
+ out.write("\t\t\titem_level {} {};\n".format(it.droplevel, upgrade_level-1))
else:
out.write('\t\t\tbase_type "{}";\n'.format(it.name))
out.write("\t\t\tmin_item_level {};\n".format(it.droplevel))