9 def __init__(self, name, kind):
14 self.upgrades = {"attrs":None, "mods":None}
16 def is_compatible(self, other):
17 return self.kind==other.kind
19 def compare_mods(self, other):
21 for n, v in self.mods.items():
22 ov = other.mods.get(n, 0)
28 for on, ov in other.mods.items():
29 v = self.mods.get(on, 0)
37 def compare_attrs(self, other):
40 def check_upgrade(self, other):
41 if not self.is_compatible(other):
44 mods = self.compare_mods(other)
45 attrs = self.compare_attrs(other)
47 if self.droplevel<other.droplevel and (mods<0 or attrs<0):
50 if not other.upgrades["mods"]:
51 if mods>0 or (mods==0 and attrs>0):
52 other.upgrades["mods"] = self
53 if not other.upgrades["attrs"]:
54 if attrs>0 or (attrs==0 and mods>0):
55 other.upgrades["attrs"] = self
58 def __init__(self, name, kind):
59 super(Armor, self).__init__(name, kind)
63 self.energy_shield = 0
65 def is_compatible(self, other):
66 if (self.armor!=0)!=(other.armor!=0):
68 if (self.evasion!=0)!=(other.evasion!=0):
70 if (self.energy_shield!=0)!=(other.energy_shield!=0):
73 return super(Armor, self).is_compatible(other)
75 def compare_attrs(self, other):
76 if self.armor<other.armor:
78 if self.evasion<other.evasion:
80 if self.energy_shield<other.energy_shield:
83 if self.armor>other.armor:
85 if self.evasion>other.evasion:
87 if self.energy_shield>other.energy_shield:
93 def __init__(self, name, kind):
94 super(Weapon, self).__init__(name, kind)
99 def compare_attrs(self, other):
100 if self.dps<other.dps:
102 if self.dps>other.dps:
107 class ItemDataParser(html.parser.HTMLParser):
109 super(ItemDataParser, self).__init__()
111 self.in_items_table = False
115 self.current_item = None
116 self.in_heading = False
118 self.current_heading = None
123 def handle_starttag(self, tag, attrs):
126 if n=="class" and v=="itemDataTable":
127 self.in_items_table = True
131 if n=="class" and v.endswith("_mod"):
135 self.current_item = None
141 self.in_heading = True
143 def handle_endtag(self, tag):
145 self.in_items_table = False
149 if self.current_item and self.mod_row:
150 for it in self.items:
151 self.current_item.check_upgrade(it)
153 self.in_heading = False
155 for i in range(1, len(self.items)):
157 self.items[j].check_upgrade(self.items[i])
159 def handle_data(self, data):
165 self.current_heading = data
166 if self.current_heading=="Staff":
167 self.current_heading = "Stave"
168 self.headings.append(self.current_heading)
169 elif self.in_items_table and self.in_cell:
172 self.mod_names.append(data)
176 value = int(data.split(" to ", 1)[1])
179 name = self.mod_names[self.mod_index]
180 if name!="From Armour Movement Speed +%":
181 self.current_item.mods[name] = value
185 self.current_item = self.create_item(data, self.current_heading)
186 self.items.append(self.current_item)
188 self.current_item.droplevel = int(data)
190 self.handle_value(self.column, data)
192 def create_item(self, name, kind):
195 def handle_value(self, column, data):
198 class ArmorDataParser(ItemDataParser):
199 def create_item(self, name, kind):
200 return Armor(name, kind)
202 def handle_value(self, column, data):
204 self.current_item.armor = int(data)
206 self.current_item.evasion = int(data)
208 self.current_item.energy_shield = int(data)
210 class WeaponDataParser(ItemDataParser):
211 def create_item(self, name, kind):
212 return Weapon(name, kind)
214 def handle_value(self, column, data):
216 self.current_item.speed = float(data)
218 self.current_item.dps = float(data)
220 def get_upgrade_level(item, steps):
222 for p in item.upgrades.keys():
224 for i in range(steps):
225 upgrade = upgrade.upgrades.get(p)
228 level = max(level, upgrade.droplevel)
231 def write_best_category(out, prefix, items, steps):
232 best = ["best", "second"]
234 out.write('category "{}.{}_at_level"\n'.format(prefix, best[steps-1]))
235 out.write("{\n\tor\n\t{\n")
237 upgrade_level = get_upgrade_level(it, steps)
238 out.write("\t\tand\n\t\t{\n")
240 out.write('\t\t\tbase_type "{}";\n'.format(it.name))
241 out.write("\t\t\titem_level {} {};\n".format(it.droplevel, upgrade_level-1))
243 out.write('\t\t\tbase_type "{}";\n'.format(it.name))
244 out.write("\t\t\tmin_item_level {};\n".format(it.droplevel))
245 out.write("\t\t};\n")
246 out.write("\t};\n};\n")
248 def print_debug(items):
251 for u in it.upgrades.values():
260 if it.name not in upgrades and it.name not in printed:
269 if it.name in printed:
274 print(" level: {}".format(it.droplevel))
275 if isinstance(it, Armor):
276 print(" armor: {}".format(it.armor))
277 print(" evasion: {}".format(it.evasion))
278 print(" energy shield: {}".format(it.energy_shield))
279 elif isinstance(it, Weapon):
280 print(" dps: {}".format(it.dps))
281 for n, v in it.mods.items():
282 print(" {}: {}".format(n, v))
283 for t, u in it.upgrades.items():
285 print(" upgrade {}: {}".format(t, u.name))
286 if u.name not in printed:
290 parser = argparse.ArgumentParser()
291 parser.add_argument("-g", "--debug", action="store_true", dest="debug")
292 args = parser.parse_args()
294 r = requests.get("https://www.pathofexile.com/item-data/armour")
295 p = ArmorDataParser()
296 p.feed(codecs.decode(r.content, r.encoding))
301 types = {"robe": lambda i: (not i.armor and not i.evasion and i.energy_shield),
302 "cloth": lambda i: (not i.armor and i.evasion and i.energy_shield),
303 "leather": lambda i: (not i.armor and i.evasion and not i.energy_shield),
304 "scale": lambda i: (i.armor and i.evasion and not i.energy_shield),
305 "plate": lambda i: (i.armor and not i.evasion and not i.energy_shield),
306 "chain": lambda i: (i.armor and not i.evasion and i.energy_shield)}
308 out = open("armor.txt", "w")
310 for t, f in types.items():
311 items = [i for i in p.items if f(i)]
313 for i in range(1, 3):
314 write_best_category(out, "armor.{}".format(t), items, i)
316 out.write('category "armor.{}"\n'.format(t))
317 out.write("{\n\tor\n\t{\n")
319 out.write('\t\tbase_type "{}";\n'.format(it.name))
320 out.write("\t};\n};\n")
322 for b in ("best", "second"):
323 out.write('category "armor.{}_at_level"\n'.format(b))
324 out.write('{\n\tor\n\t{\n')
325 for t in types.keys():
326 out.write('\t\tcategory "armor.{}.{}_at_level";\n'.format(t, b))
327 out.write("\t};\n};\n")
329 out.write('category "armor"\n{\n\tor\n\t{\n')
331 out.write('\t\tclass "{}";\n'.format(h))
332 out.write("\t};\n};\n")
334 r = requests.get("https://www.pathofexile.com/item-data/weapon")
335 p = WeaponDataParser()
336 p.feed(codecs.decode(r.content, r.encoding))
341 out = open("weapons.txt", "w")
344 items = [i for i in p.items if i.kind==h]
346 for i in range(1, 3):
347 write_best_category(out, "weapon.{}".format(h.lower().replace(' ', '_')), items, i)
349 for b in ("best", "second"):
350 out.write('category "weapon.{}_at_level"\n'.format(b))
351 out.write('{\n\tor\n\t{\n')
353 out.write('\t\tcategory "weapon.{}.{}_at_level";\n'.format(h.lower().replace(' ', '_'), b))
354 out.write("\t};\n};\n")
356 out.write('category "weapon"\n{\n\tor\n\t{\n')
358 out.write('\t\tclass "{}";\n'.format(h))
359 out.write("\t};\n};\n")
361 if __name__=="__main__":